Professional Documents
Culture Documents
Khoa CNTT
Chương 6:
MẢNG và CHUỖI KÍ TỰ
1
&&
VC
VC
BB
BB
Nội dung
1 Mảng 1 chiều
Ví dụ
Chương trình cần lưu trữ 3 số nguyên?
=> Khai báo 3 biến int a1, a2, a3;
Chương trình cần lưu trữ 100 số nguyên?
=> Khai báo 100 biến kiểu số nguyên!
Người dùng muốn nhập n số nguyên?
=> Không thực hiện được!
Giải pháp
Kiểu dữ liệu mới cho phép lưu trữ một dãy
các số nguyên và dễ dàng truy xuất.
NMLT - Mảng một chiều 3
&&
VC
VC
BB
BB
1. Mảng 1 chiều
• Lưu ý
• Phải xác định <số phần tử> cụ thể (hằng) khi khai báo.
(VD khai báo: int a[ ]=> Lỗi)
• Bộ nhớ sử dụng = <tổng số phần tử>*sizeof(<kiểu cơ sở>)
• Bộ nhớ sử dụng phải ít hơn 64KB (65535 Bytes)
• Một dãy liên tục có chỉ số từ 0 đến <tổng số phần tử>-1
(Nếu ta có mảng a có khai báo int a[20] thì các phần tử của
nó có thứ tự (chỉ số) từ 0 đến 19)
NMLT - Mảng một chiều 5
&&
VC
VC
BB
BB
Khai báo biến mảng
int Mang1Chieu[10];
0 1 2 3 4 5 6 7 8 9
Mang1Chieu
• Ví dụ
typedef int Mang1Chieu[10]; //ĐN kiểu DL mới tên Mang1Chieu
typedef int Mang2Chieu[3][4]; //ĐN kiểu DL mới tên Mang2Chieu
//Sử dụng 2 kiểu Dl này để khai báo các biến m1, m2, m3, m4,m5
Mang1Chieu m1, m2, m3;
Mang2Chieu m4, m5;
NMLT - Mảng một chiều 7
&&
VC
VC
BB
BB
1.2. Số phần tử của mảng
Phải xác định cụ thể số phần tử ngay lúc khai
báo, không được sử dụng biến hoặc hằng
thường (hằng phải được khai báo bằng #define
không được khai báo bằng const)
int n1 = 10; int a[n1]; //báo lỗi vì sd biến để khai báo số pt mảng
const int n2 = 20; int b[n2]; //báo lỗi vì sd hằng thường
a 0 0 0 0
Tự động xác định số lượng phần tử
int a[] = {2912, 1706, 1506, 1904};
0 1 2 3
int a[4];
Các truy xuất
• Hợp lệ: a[0], a[1], a[2], a[3]
• Không hợp lệ: a[-1], a[4], a[5], …
=> Cho kết quả thường không như mong muốn!
Ví dụ
#define MAX 3 //ĐN 1 hằng số tên là MAX có giá trj là 3
typedef int MangSo[MAX]; //ĐN 1 kiểu dữ liệu tên MangSo
MangSo a = {1, 2, 3}, b; // Khao báo biến a là 1 MangSo, gán trị
cho mảng a, khai báo 1 biến b là 1 MangSo
b = a; // Sai do ko thể gán 2 mảng cho nhau
for (int i = 0; i < MAX; i++)
b[i] = a[i]; NMLT - Mảng một chiều 12
&&
VC
VC
BB
BB
Một số lỗi thường gặp
double a[30];
int a;
double a[30];
int a;
Yêu cầu
Cho phép nhập mảng a, số lượng phần tử n
Ý tưởng
Cho trước một mảng có số lượng phần tử là MAX.
Nhập số lượng phần tử thực sự n của mảng.
Nhập từng phần tử cho mảng từ chỉ số 0 đến n – 1.
0 1 2 3 n -4 1 MAX - 1
… … …
Yêu cầu
Cho trước mảng a, số lượng phần tử n. Hãy xuất nội
dung mảng a ra màn hình.
Ý tưởng
Xuất giá trị từng phần tử của mảng từ chỉ số 0 đến n-1.
0 1 2 n-1 MAX - 1
… … …
cout<<“\n";
}
Yêu cầu
Tìm xem phần tử x có nằm trong mảng a kích thước n
hay không? Nếu có thì nó nằm ở vị trí đầu tiên nào.
Ý tưởng
Xét từng phần của mảng a. Nếu phần tử đang xét bằng
x thì trả về vị trí đó. Nếu kô tìm được thì trả về -1.
x vị trí = 1
0 1 2 n-1 MAX - 1
a x b … x … …
if (vt < n)
return vt;
else
return -1;
}
return -1;
}
Yêu cầu
Cho trước mảng a, số lượng phần tử n. Mảng a có
phải là mảng toàn các số nguyên tố hay không?
Ý tưởng
Cách 1: Đếm số lượng số ngtố của mảng. Nếu số
lượng này bằng đúng n thì mảng toàn ngtố.
Cách 2: Đếm số lượng số không phải ngtố của mảng.
Nếu số lượng này bằng 0 thì mảng toàn ngtố.
Cách 3: Tìm xem có phần tử nào không phải số ngtố
không. Nếu có thì mảng không toàn số ngtố.
if (dem == n)
return 1;
return 0;
}
if (dem == 0)
return 1;
return 0;
}
return 1;
}
Yêu cầu
Cho trước mảng a, số lượng phần tử na. Tách các số
nguyên tố có trong mảng a vào mảng b.
Ý tưởng
Duyệt từ phần tử của mảng a, nếu đó là số nguyên tố
thì đưa vào mảng b.
Yêu cầu
Cho trước mảng a, số lượng phần tử na. Tách mảng
a thành 2 mảng b (chứa số nguyên tố) và mảng c
(các số còn lại).
Ý tưởng
Cách 1: viết 1 hàm tách các số nguyên tố từ mảng a
sang mảng b và 1 hàm tách các số không phải
nguyên tố từ mảng a sang mảng c.
Cách 2: Duyệt từ phần tử của mảng a, nếu đó là số
nguyên tố thì đưa vào mảng b, ngược lại đưa vào
mảng c.
Yêu cầu
Cho trước mảng a, số lượng phần tử na và mảng b
số lượng phần tử nb. Gộp 2 mảng trên theo tứ tự đó
thành mảng c, số lượng phần tử nc.
Ý tưởng
Chuyển các phần tử của mảng a sang mảng c
=> nc = na
Tiếp tục đưa các phần tử của mảng b sang mảng c
=> nc = nc + nb
Yêu cầu
Cho trước mảng a có n phần tử. Tìm giá trị lớn nhất
trong a (gọi là max)
Ý tưởng
Giả sử giá trị max hiện tại là giá trị phần tử đầu tiên a[0]
Lần lượt kiểm tra các phần tử còn lại để cập nhật max.
max 8
7
?
0 1 2 n–1 MAX - 1
7 2 8 … 8 … …
return max;
}
Yêu cầu
Cho trước mảng a kích thước n. Hãy sắp xếp mảng a
đó sao cho các phần tử có giá trị tăng dần.
Ý tưởng
Sử dụng 2 biến i và j để so sánh tất cả cặp phần tử
với nhau và hoán vị các cặp nghịch thế (sai thứ tự).
tạm 5
8
0 1 2 n–1 MAX - 1
5
1 1
5 8
6 … 6
8 … …
40
i j j j j NMLT - Mảng một chiều
&&
VC
VC
BB
BB
Hàm Sắp Xếp Tăng
Yêu cầu
Thêm phần tử x vào mảng a kích thước n tại vị trí vt.
Ý tưởng
“Đẩy” các phần tử bắt đầu tại vị trí vt sang phải 1 vị trí.
Đưa x vào vị trí vt trong mảng.
Tăng n lên 1 đơn vị.
x chèn?
0 1 2 3 n–1 n MAX - 1
a b c … z … …
a[vt] = x;
n++;
}
}
Yêu cầu
Xóa một phần tử trong mảng a kích thước n tại vị trí vt
Ý tưởng
“Kéo” các phần tử bên phải vị trí vt sang trái 1 vị trí.
Giảm n xuống 1 đơn vị.
xóa?
a x b … z … …
n--;
}
}
Ma Trận
0 1 … n-1 0 … n-1
0 0
Am,n An
…
…
m-1 n-1
0 0 0
An
…
…
n-1 n-1 n-1
0 0 0
An
…
…
n-1 n-1 n-1
dòng + cột = n-1 dòng + cột > n-1 dòng + cột < n-1
NMLT - Mảng hai chiều 47
&&
VC
VC
BB
BB
2.1. Khai báo biến mảng 2 chiều
Cú pháp
Tường minh
<kiểu cơ sở> <tên biến>[<N1>][<N2>];
Ví dụ
0 1 2 3
Kiểu MaTran 1
Ví dụ
int Mang2Chieu[3][4];
0 1 2 3 4 5 6 7 8 9 10 11
Mang2Chieu 0
1
Ví dụ
Tường minh
int a[10][20], b[10][20];
int c[5][10];
int d[10][20];
Không tường minh (thông qua kiểu)
typedef int MaTran10x20[10][20];
typedef int MaTran5x10[5][10];
MaTran10x20 a, b;
MaTran11x11 c;
MaTran10x20 d;
Ví dụ 0 1 2 3
1
int a[3][4];
2
Các truy xuất
• Hợp lệ: a[0][0], a[0][1], …, a[2][2], a[2][3]
• Không hợp lệ: a[-1][0], a[2][4], a[3][3]
b = a; // Sai
int i, j;
for (i = 0; i < 5; i++)
for (j = 0; j < 10; j++)
b[i][j] = a[i][j];
NMLT - Mảng hai chiều 53
&&
VC
VC
BB
BB
2.4. Truyền mảng cho hàm
Viết chương trình con thực hiện các yêu cầu sau
Nhập mảng
Xuất mảng
Tìm kiếm một phần tử trong mảng
Kiểm tra tính chất của mảng
Tính tổng các phần tử trên dòng/cột/toàn ma
trận/đường chéo chính/nửa trên/nửa dưới
Tìm giá trị nhỏ nhất/lớn nhất của mảng
…
Yêu cầu
Cho phép nhập mảng a, m dòng, n cột
Ý tưởng
Cho trước một mảng 2 chiều có dòng tối đa là MAXD,
số cột tối đa là MAXC.
Nhập số lượng phần tử thực sự m, n của mỗi chiều.
Nhập từng phần tử từ [0][0] đến [m-1][n-1].
int i, j;
for (i=0; i<m; i++)
for (j=0; j<n; j++)
{
cout<<Nhap a[“<<i<<“][“<j<<“]:”;
cin>>a[i][j];
}
}
Yêu cầu
Cho phép nhập mảng a, m dòng, n cột
Ý tưởng
Xuất giá trị từng phần tử của mảng 2 chiều từ dòng
có 0 đến dòng m-1, mỗi dòng xuất giá giá trị của cột 0
đến cột n-1 trên dòng đó.
cout<<“\n";
}
}
Yêu cầu
Tìm xem phần tử x có nằm trong ma trận a kích
thước mxn hay không?
Ý tưởng
Duyệt từng phần của ma trận a. Nếu phần tử đang
xét bằng x thì trả về có (1), ngược lại trả về không có
(0).
Yêu cầu
Cho trước ma trận a kích thước mxn. Ma trận a có
phải là ma trậntoàn các số nguyên tố hay không?
Ý tưởng
Cách 1: Đếm số lượng số ngtố của ma trận. Nếu số
lượng này bằng đúng mxn thì ma trận toàn ngtố.
Cách 2: Đếm số lượng số không phải ngtố của ma
trận. Nếu số lượng này bằng 0 thì ma trận toàn ngtố.
Cách 3: Tìm xem có phần tử nào không phải số ngtố
không. Nếu có thì ma trận không toàn số ngtố.
tong = 0;
return tong;
}
tong = 0;
return tong;
}
tong = 0;
return tong;
}
tong = 0;
return tong;
}
tong = 0;
return tong;
}
tong = 0;
return tong;
}
Yêu cầu
Cho trước ma trận a, kích thước mxn. Tìm giá trị lớn
nhất trong ma trận a (gọi là max)
Ý tưởng
Giả sử giá trị max hiện tại là giá trị phần tử đầu tiên a[0]
[0]
Lần lượt kiểm tra các phần tử còn lại để cập nhật max.
max = a[0][0];
return max;
}
Sinh viên truy cập vào link sau để làm bài kiểm tra
ôn tập chương 6:
https://docs.google.com/forms/d/e/
1FAIpQLSdjF6uNM8uVs6e_yQKoOSys-O9a4wJgFV-
KXR6Z5SxN_N0Aww/viewform?usp=sf_link
72