You are on page 1of 54

Chương 6.

MẢNG
1. Giới thiệu
2. Mảng – Các ví dụ về mảng
3. Truyền tham số cho mảng
4. Sắp xếp mảng
5. Tìm Mean, median, mode sử dụng mảng
6. Tìm dữ liệu của mảng
7. Mảng 2 chiều
1. Giới thiệu
• Mảng là tập hợp các phần tử có cùng dữ liệu
• Có cấu trúc tĩnh – Cùng kích thước xuyên suốt chương
trình
• Một nhóm các địa chỉ nhớ liên tiếp
2. Mảng
• Để tham chiếu đến một phần tử, xác định
Tên mảng
Vị trí
• Định dạng:
Ten_mang [vi_tri]
• Tên của các phần tử của mảng c có n phần tử là
c[0], c[1],...c[n-1]
• Định nghĩa mảng
Kieu_du_lieu ten_mang[so_phan_tu]
VD: int c[10]
• Khởi tạo mảng
int n[5] = {1,2,3,4,5}
int n[5] = {0}
int n[ ] = {1,2,3,4,5}
Nhập và đọc dữ liệu mảng
• Nhập dữ liệu:
for (i = 0; i < 10; i++)
{
printf("enter element %d\n", i);
scanf("%d", &s[i]);
}
• Đọc dữ liệu từ mảng:
for (i = 0; i < 10; i++)
{printf("%7d%13d\n", i, n[i]);
VD mảng
1. Nhập và xuất 1 mảng 10 phần tử theo cột gồm cột tên
phần tử và giá trị
2. Nhập và xuất 1 mảng 10 phần tử theo cột với các
phần tử là 0
3. Khởi tạo 1 mảng 10 phần tử và in ra theo cột
4. Sử dụng định nghĩa size để khai báo mảng, giá trị
mảng s[i] = 2+2i xuất theo cột
5. Nhập, xuất các phần tử của mảng 10 phần tử và tính
tổng các phần tử
6. In số hình ngôi sao tương ứng với dữ liệu cho trước
trong mảng
7. Thống kê kết quả khảo sát
#include <stdio.h>
#include <conio.h>
int main(void){
int a[10];
int i;
for (i = 0; i < 10; i++){
printf("enter value %d\n", i + 1);
scanf("%d", &a[i]);
}
printf("%s%10s\n", "element", "value");
for (i = 0; i < 10; i++)
printf("%4d%10d\n", i+1, a[i]);
getch();
}
#include <stdio.h>
#include <conio.h>
int main(void)
{
int n[10];
int i;
for (i = 0; i < 10; i++)
{n[i] = 0;}
printf("%s%13s\n","Element","Value");
for (i = 0; i < 10; i++)
{printf("%7d%13d\n", i, n[i]);}
getch();
}
#include <stdio.h>
#include <conio.h>
int main(void)
{
int n[10] = { 32, 27, 64, 18, 95, 14, 90,
70, 60, 37 };
int i;
printf("%s%13s\n", "Element", "Value");
for (i = 0; i < 10; i++)
{
printf("%7d%13d\n", i, n[i]);
}
getch();
}
#include <stdio.h>
#include <conio.h>
#define size 10
int main(void)
{
int s[size];
int j;
for (j = 0; j < size; j++)
{s[j] = 2 + 2 * j;}
printf("%s%13s\n", "Element", "Value");
for (j = 0; j < size; j++)
{printf("%7d%13d\n", j, s[j]);}
getch();
}
#include <stdio.h>
#include <conio.h>
#define size 10
int main(void){
int s[size];
int sum = 0,j;
for (j = 1; j <= size; j++){
printf("enter element %d\n", j);
scanf("%d", &s[j]);
}
printf("s[%d] = {",size);
for (j = 1; j <= size; j++){
sum = sum + s[j];
if (j == (size))
printf("%3d", s[j]);
else
printf("%3d,", s[j]);
}
printf("}\n Sum of all elements is = %d ",sum);
getch();
}
#include <stdio.h>
#include <conio.h>
#define SIZE 10
int main(void)
{
int n[SIZE] = { 19, 3, 15, 7, 11, 9, 13, 5, 17, 1 };
int i, j;
printf("%s%13s%17s\n", "Element", "Value", "Histogram");
for (i = 0; i < SIZE; i++)
{
printf("%7d%13d ", i, n[i]);
for (j = 1; j <= n[i]; j++)
{ printf("%c", '*');} // printf("*");
printf("\n");
}
getch();
}
#include <stdio.h>
#include <conio.h>
#define RES_S 40
#define FRE_S 11
int main(void){
int answer,rating;
int fre[FRE_S] = { 0 };
int responses[RES_S] = { 1, 2, 6, 4, 8, 5, 9, 7,
8, 10,1, 6, 3, 8, 6, 10, 3, 8, 2, 7, 6, 5, 7, 6, 8, 6,
7, 5, 6, 6,5, 6, 7, 5, 6, 4, 8, 6, 8, 10 };
for (answer = 0; answer < RES_S; answer++)
++fre[responses[answer]];
printf("%s%17s\n", "Rating", "Frequency");
for (rating = 1; rating < FRE_S; rating++)
printf("%6d%17d\n", rating, fre[rating]);
getch();
}
• Tính số lần xuất hiện:
+ Cách 1: sử dụng switch, if
+ Sử dụng mảng
VD: A [14] = { 4 , 1 , 6 , 2 , 1 , 5 , 6 , 4 , 2 , 3 , 1 , 3 , 5 , 6 }

B[7] = {0 } = { 0,0,0,0,0,0,0}

for ( int i = 0; i<=13; i++)


++B[A[i]];
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 7
int main( void ) {
size_t face; // random die value 1 - 6
unsigned int roll; // roll counter 1-6,000,000
unsigned int frequency[ SIZE ] = { 0 }; // clear
counts
srand( time( NULL ) );
for ( roll = 1; roll <= 6000000; ++roll ) {
face = 1 + rand() % 6; // end for
++frequency[face];
}
printf( "%s%17s\n", "Face", "Frequency" );
for ( face = 1; face < SIZE; ++face ) {
printf( "%4d%17d\n", face, frequency[ face ] );
}
_getch();
}
Mảng ký tự
• Khai báo mảng ký tự: char string1[ ] = "first";
Trong đó có 5 ký tự (f-i-r-s-t)và 1 ký tự đặc biệt “\0” – Ký
tự kết thúc
→có 6 ký tự
• Có thể khởi tạo cách khác:
char string1[ ] = { 'f', 'i', 'r', 's', 't', '\0' };
• Có thể tham chiếu đến một ký tự của mảng
string1[ 3 ] là ký tự ‘s’
• Khi sử dụng đọc mảng ký tự
scanf( "%s", string2 );
Đọc dữ liệu đến khi gặp phải tab, khoảng trắng, enter, eof
(end of file)
VD. In chuỗi được nhập, chuỗi đã được khởi tạo, cho
khoảng thắng vào chuỗi đã nhập
#include <stdio.h>
#include <conio.h>
int main(void){
char string1[20];
char string2[] = "string example";
int i;
printf("Enter a string: ");
gets_s(string1);
printf("string1 is: %s\nstring2 is: %s\n"
"string1 with spaces between characters is:\n",
string1, string2);
for (i = 0; string1[i] != '\0'; i++){
printf("%c ", string1[i]);
}
printf("\n");
_getch();
}
Cho nhập chuỗi, Nhập ký tự cần tìm c. In ra có bao nhiêu
ký tự c trong chuỗi

int main(void){
char string1[20];
int j = 0 , i; char c;
printf("Enter a string: ");
gets_s(string1);
printf("Enter a character: ");
scanf_s("%c",&c);
for (i = 0; string1[i] != '\0' ; i++){
if (string1[i] == c) j++;
}
if (j != 0)
printf("Have %d character %c in string",j,c);
else printf("Have no character %c in string", c);
}
for (i = 0; i <= strlen(string1); i++){
if (string1[i] == c)
j++;
}

strlen(); nằm trong thư viện #include <string.h>


3. Truyền mảng cho hàm
• Truyền mảng
• Truyền tên mảng, bỏ dấu [ ]
VD: truyền mảng array1 đến hàm function1
int array1[50];
function1(array1, 50);
Kích thước mảng thường được truyền nhưng không nhất
thiết
• Mảng truyền tham chiếu
• Tên của mảng là địa chỉ của phần tử đầu tiên
• Hàm sẽ biết nơi nào mảng được lưu trữ
• Truyền phần tử mảng – truyền tham trị
• Truyền tên phần tử (VD: array1[1]) đến hàm
3. Truyền mảng cho hàm
• Hàm nguyên mẫu:
void modifyArray( int b[], int arraySize );
• Trong đó:
int b[ ] có thể được viết int [ ]
int arraySize có thể được viết int
VD: Vị trí mảng là vị trí đầu tiên
của phẩn tử
#include <stdio.h>
#include <conio.h>
int main(void)
{
char array[5];
printf(" array = %p\n&array[0] = %p\n
&array = %p\n", array, &array[0], &array);
getch();
}
VD:
• Viết hàm nhân đôi các phần tử của 1 mảng. Đối số cấp
cho hàm là Mảng và kích thước của mảng
• Viết CT sử dụng hàm đã viết để in ra mảng (khởi tạo) đã
được nhân đôi các phần tử
• In lại mảng ban đầu và kết luận về cách truyền đối số (là
mảng) cho cho hàm
void modifyArray(int b[], int size) {
int j;
printf("The values of the modified array
are:\n");
for (j = 0; j < size; j++) {
b[j] *= 2;
printf("%3d", b[j]);
}
}
#include <stdio.h>
#include <conio.h>
#define SIZE 5
void modifyArray(int b[], int size);
int main(void) {
int a[SIZE] = { 0, 5, 2, 8, 4 };
int i;
printf("The values of the original array are:\n");
for (i = 0; i < SIZE; i++) {
printf("%3d", a[i]);} 0 5 2 8 4
printf("\n");
modifyArray(a, SIZE); 0 10 4 16 8
printf("\nThe values of array are:\n");
for (i = 0; i < SIZE; i++) {
printf("%3d", a[i]);} 0 10 4 16 8
getch();
}
VD truyền tham chiếu mảng và truyền tham
trị giá trị phần tử mảng
• Nhập 1 mảng bất kỳ, xuất giá trị mảng vừa nhập
• Viết hàm nhân đôi mỗi giá trị của mảng vừa nhập, gọi hàm để
nhân đôi mảng vừa nhập. In kết quả → kết luận về cách truyền
• Viết hàm nhân đôi giá trị phần tử, gọi hàm để nhân đôi giá trị
thứ 3 trong mảng. In kết quả → kết luận về cách truyền
#include <stdio.h>
#include <conio.h>
#define SIZE 5
void modifyArray(int b[], int size);
void modifyElement(int e);
int main(void)
{
int a[SIZE] = { 0, 5, 2, 8, 4 };
int i;
printf("The values of the original array are:\n");
for (i = 0; i < SIZE; i++)
{ printf("%3d", a[i]);}
printf("\n");
modifyArray(a, SIZE);
printf("\nThe values of array are:\n");
for (i = 0; i < SIZE; i++)
{printf("%3d", a[i]);}
printf("\nThe value of a[3] is %d\n", a[3]);
modifyElement(a[3]);
printf("The value of a[3] is %d\n", a[3]);
getch();
}
void modifyArray(int b[], int size)
{
int j;
printf("The values of the modified array are:\n");
for (j = 0; j < size; j++)
{ b[j] *= 2;
printf("%3d", b[j]);
}
}
void modifyElement(int e)
{printf("Value in modifyElement is %d\n", e *= 2);}
Const array
#include <stdio.h>
#include <conio.h>
void tryToModifyArray(const int b[]);
int main(void){
int a[] = { 10, 20, 30 };
tryToModifyArray(a);
printf("%d %d %d\n", a[0], a[1], a[2]);
}
void tryToModifyArray(const int b[]) {
b[0] /= 2; // error
b[1] /= 2; // error
b[2] /= 2; // error
}
VD Viết CT sử dụng static

• Tạo hàm auto_array: Khởi tạo và hiển thị mảng auto 3 giá trị,
Tăng 5 đơn vị cho mỗi phần tử hàm vừa tạo, in kết quả
• Tạo hàm static_array: Khởi tạo và hiển thị mảng static có 3 giá
trị. Tăng 5 đơn vị cho mỗi phần tử vừa tạo, in kết quả
• Viết CT chính lần lượt gọi 2 hàm vừa tạo 2 lần →kết luận kết
quả
void autoArrayInit(void){
int array2[3] = { 1, 2, 3 };
int i;
puts("\n\nValues on entering autoArrayInit:");
for (i = 0; i <= 2; ++i) {
printf("array2[ %u ] = %d ", i, array2[i]);
}
puts("\nValues on exiting autoArrayInit:");
for (i = 0; i <= 2; ++i) {
printf("array2[%u] = %d", i,array2[i] += 5);
}
}
void staticArrayInit(void) {
static int array1[3] = {1,2,3};
int i;
puts("\nValues on entering staticArrayInit:");
for (i = 0; i <= 2; ++i) {
printf("array1[ %u ] = %d ", i, array1[i]);
}
puts("\nValues on exiting staticArrayInit:");
for (i = 0; i <= 2; ++i) {
printf("array1[%u] = %d ", i,array1[i] += 5);
}
}
#include <stdio.h>
#include <conio.h>
void staticArrayInit(void);
void automaticArrayInit(void);
int main(void){
puts("First call to each function:");
staticArrayInit();
automaticArrayInit();
puts("\n\nSecond call to each function:");
staticArrayInit();
automaticArrayInit();
_getch();
}
4. Sort mảng
• Sắp xếp mảng
Là một ứng dụng quan trọng trong tính toán
Tất cả các tổ chức đều sắp xếp dữ liệu
• Bubble sort (sắp xếp nổi bọt): Sắp xếp mảng có giá trị tăng dần
• So sánh 2 cặp phần tử liền kề, hoán đổi vị trí nếu chưa đúng
thứ tự và lặp lại đến hết
• VD: dãy số ban đầu: 4 5 2 9 3 7
4 2 5 9 3 7
2 4 5 9 3 7
2 4 5 3 9 7
2 4 3 5 9 7
2 3 4 5 9 7
2 3 4 5 7 9
VD: Sắp xếp mảng
• Khởi tạo và in ra mảng gồm 10 số tự nhiên bất kỳ
• Sắp xếp và in ra mảng đã sắp xếp từ nhỏ đến lớn
• In ra mảng đã sắp xếp từ lớn đến nhỏ
while(i < (SIZE -1))
{
if (a[i] > a[i + 1])
{
hold = a[i];
a[i] = a[i + 1];
a[i + 1] = hold;
i = 0;
}
else
i++;
}
void sapxep (int A[], int n){
int hold;
for (int pass = 1; pass < n; pass++) {
for (int i = 0; i < n -1 ; i++) {
if (a[i] > a[i + 1]) {
hold = a[i];
a[i] = a[i + 1];
a[i + 1] = hold;
}
}
}
void sapxep (int a[], int n){
int hold;
for (int i = 0; i < n; i++) {
for (j = i+1; j < n ; j++) {
if (a[i] > a[j]) {
hold = a[i];
a[i] = a[j];
a[j] = hold;
}
}
}
}
#include <stdio.h>
#include <conio.h>
#define SIZE 10
int main(void){
int a[SIZE] = { 4, 6, 2, 8, 10, 12, 89, 68, 45, 37 };
int pass, i, hold;
printf("Data items in original order\n");
for (i = 0; i < SIZE; i++)
{ printf("%4d", a[i]);}
for (pass = 1; pass < SIZE; pass++) {
for (i = 0; i < SIZE -1 ; i++) {
if (a[i] > a[i + 1]) {
hold = a[i];
a[i] = a[i + 1];
a[i + 1] = hold;
}
}
}
printf("\nData items in ascending order\n");
for (i = 0; i < SIZE; i++)
{ printf("%4d", a[i]);}
printf("\n");
getch();
}
5. Tính Mean, median, mode
• Mean – Trung bình
• Median – Số ở giữa 1 danh sách đã được sắp xếp
• Mode – Số có số lần xuất hiện nhiều nhất
• VD: Viết chương trình tính và in ra Mean, Median, Mảng đã được sắp
xếp. Liệt kê số lần xuất hiện các giá trị của mảng và in ra số lượng *
tương ứng theo 3 cột → in ra Mode
Khởi tạo mảng có các phần tử sau
67898789897895987878
67893987877898989789
67878798927898989753
56725394647896878978
7442538756456165787
• Viết hàm tìm Mean biết: đối số cấp cho hàm là mảng, in ra giá
trị trung bình
• Median: là số giữa một dãy số đã được sắp xếp
→ Viết hàm sắp xếp: đối số cấp cho hàm là mảng, in ra mảng đã
được sắp xếp
→ Viết hàm tìm Median, đối số cấp cho hàm là mảng, in ra giá
trị Median
• Mode: Số lần xuất hiện nhiều nhất
→Tìm số lần xuất hiện mỗi số
→In histogram
→Tìm số lớn nhất trong mảng (Mode)
6. Tìm mảng
• Sử dụng giá trị “key”
• Tìm kiếm tuyến tính:
Đơn giản
So sánh mỗi phần tử với key đến khi tìm thấy
Phù hợp với những mảng chưa được sắp xếp và nhỏ
• VD: Tạo 1 mảng gồm 10 phần tử theo công thức a[i] = 2*i
Viết hàm tìm kiếm 1 số bất kỳ trong mảng
Sử dụng hàm tìm kiếm vị trí giá trị trong mảng
Đổi mảng vừa sử dụng thành 1 mảng gồm các phần tử
giống nhau
Gọi lại hàm cho biết kết quả tìm kiếm
Viết hàm để xuất hết các vị trí có cùng giá trị
int linearSearch(const int array[], int key,
int size)
{
int n;
for (n = 0; n < size; ++n)
{
if (array[n] == key)
{ return n; }
}
return -1;
}
for (x = 0; x < SIZE; x++)
{
a[x] = 2 * x;
printf("%5d", a[x]);
}
printf("\nEnter integer search key:\n");
scanf("%d", &searchKey);
element = linearSearch(a, searchKey, SIZE);
if (element != -1)
{printf("Found value in element %d\n",
element); }
else
{printf("Value was not found in array\n");}
6. Tìm mảng
• Tìm kiếm nhị phân
• Chỉ dùng cho mảng đã sắp xếp
• Thuật toán
So sánh key với phần tử median
Nếu lớn hơn tìm nửa sau →low
Nếu nhỏ hơn tìm nửa đầu →high
Tiếp tục đến hết
• Ưu nhược điểm
• VD: Tạo 1 mảng gồm 15 phần tử, a[i] = 2*i
Viết hàm tìm kiếm nhị phân
Hiển thị kết quả
Xác định vị trí giá trị cần tìm sử dụng hàm tìm kiếm nhị phân
7
• 0 low median 10 high
• 1 1 4 5 5 6 7 8 8 9 9
• low = me+1 me high
• 7 8 8 9 9
• low high = me -1
• 7 8
int main(void)
{
int a[SIZE];
int i, key, result;
for (i = 0; i < SIZE; i++)
{a[i] = 2 * i;}
printf("Enter a number between 0 and 28: ");
scanf("%d", &key);
result = binarySearch(a, key, SIZE);
if (result != -1)
{printf("\n%d found in array element
%d\n", key, result);}
else {printf("\n%d not found\n", key);}
getch();
}
int binarySearch(const int b[], int searchKey,
int low, int high)
{
int middle;
while (low <= high)
{
middle = (low + high) / 2;
if (searchKey == b[middle])
{return middle;}
else if (searchKey < b[middle])
high = middle - 1;
else { low = middle + 1; }
}
return -1;
}
int binarySearch(const int b[], int searchKey, int
n)
{
int middle;
int low = 0, high = n – 1;
while (low <= high)
{
middle = (low + high) / 2;
if (searchKey == b[middle])
{return middle;}
else if (searchKey < b[middle])
high = middle - 1;
else { low = middle + 1; }
}
return -1;
}
7. Mảng 2 chiều
• Khai báo mảng 2 chiều
int array2D[3][5]; // 3x5 elements (3 rows, 5 columns)
• Khởi tạo mảng 2 chiều
int array2D[3][5] = {
{ 1, 2, 3, 4, 5 }, //row 1
{ 6, 7, 8, 9, 10 }, //row 2
{ 11, 12, 13, 14, 15 } //row 3
};
int array2D[3][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
int seats[3][5] = { { 1, 2 }, //row 1 = 1, 2, 0, 0, 0
{ 6, 7, 8 }, //row 2 = 6, 7, 8, 0, 0
{ 11 }, //row 3 = 11, 0, 0, 0, 0
};
int array2D[][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 } };
7. Mảng 2 chiều
Bài tập
• Viết chương trình nhập và in ra mảng 2
chiều nxm với n,m nhập từ bàn phím
• Viết chương trình nhập vào mảng 2 chiều
5x5. Tìm giá trị và vị trí phần tử lớn nhất,
nhỏ nhất của mỗi hàng và của toàn mảng
#include <stdio.h>
#include <conio.h>
#define SIZE 20
int main(void){
char string1[SIZE];
char string2[50] = "string literal";
size_t i;
printf("%s", "Enter a string (no longer than 19
characters): ");
scanf_s("%19s", string1);
printf("string1 is: %s\nstring2 is: %s\n"
"string1 with spaces between characters
is:\n",string1, string2);
for (i = 0; i < SIZE && string1[i] != '\0'; ++i) {
printf("%c ", string1[i]);
}
puts("");
_getch();
}
int A[3][5];
int i, j, n, m;
printf("Enter array:\n");
for (i = 0; i < 3; i++){
for (j = 0; j < 5; j++){
scanf_s("%d", &A[i][j]);
}
}
int max = A[0][0];
for (i = 0; i < 3; i++){
for (j = 0; j < 5; j++){
printf("%5d", A[i][j]);
if (A[i][j] > max){
max = A[i][j];
n = i+1; m = j+1;
}
}
printf("\n");
}
printf("Max la: %d\nPhan tu hang %d cot %d", max,n,m);
int max;
int n, m;
for (i = 0; i < 3; i++){
n = 0; m = 0; max = A[i][0];
for (j = 0; j < 5; j++){
if (A[i][j] > max){
max = A[i][j];
n = i + 1; m = j + 1;
}
}
printf("Max hang %d cot %d la: %d\n", n, m, max);
}

You might also like