Tài liệu Phương pháp lập trình - Mảng một chiều, chuỗi - Ngô Hữu Dũng: Phương pháp lập trình
Mảng một chiều, chuỗi
TS. Ngô Hữu Dũng
TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP THÀNH PHỐ HỒ CHÍ MINH
Đặt vấn đề
Cần lưu trữ 10, 100, 1000 số cùng kiểu dữ liệu?
Giải pháp
Kiểu dữ liệu mảng cho phép lưu trữ một dãy các số đồng dạng.
Ví dụ
int a[10];
Tạo ra một dãy số nguyên gồm 10 phần tử
Phương pháp lập trình - Mảng, chuỗi
0 1 2 3 4 7 85 6 9
Dữ liệu kiểu mảng
Khái niệm
Kiểu dữ liệu có cấu trúc do người lập trình định nghĩa.
Biểu diễn một dãy các biến đồng dạng.
Cùng kiểu: dãy các số nguyên, dãy các số thực, dãy các ký tự
Cùng kích thước
Số lượng phần tử được xác định ngay khi khai báo.
Một khối nhớ liên tục được cấp phát cho một biến kiểu mảng.
Truy suất một phần tử: tên mảng[chỉ số]
Ví dụ mảng có n phần tử: a[0], a[1] a[n-1]
Phương pháp lập trình - Mảng, chuỗi
0 1 2 3 4 7 85 6 9
a
Khai báo mảng
Cú pháp
Ví dụ
int mangSoNguyen[10];
float mangSoThuc[100];
char chuoiKyTu[1000];
Lưu ý
Phải xác định cụ thể...
73 trang |
Chia sẻ: putihuynh11 | Lượt xem: 784 | Lượt tải: 1
Bạn đang xem trước 20 trang mẫu tài liệu Phương pháp lập trình - Mảng một chiều, chuỗi - Ngô Hữu Dũng, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Phương pháp lập trình
Mảng một chiều, chuỗi
TS. Ngô Hữu Dũng
TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP THÀNH PHỐ HỒ CHÍ MINH
Đặt vấn đề
Cần lưu trữ 10, 100, 1000 số cùng kiểu dữ liệu?
Giải pháp
Kiểu dữ liệu mảng cho phép lưu trữ một dãy các số đồng dạng.
Ví dụ
int a[10];
Tạo ra một dãy số nguyên gồm 10 phần tử
Phương pháp lập trình - Mảng, chuỗi
0 1 2 3 4 7 85 6 9
Dữ liệu kiểu mảng
Khái niệm
Kiểu dữ liệu có cấu trúc do người lập trình định nghĩa.
Biểu diễn một dãy các biến đồng dạng.
Cùng kiểu: dãy các số nguyên, dãy các số thực, dãy các ký tự
Cùng kích thước
Số lượng phần tử được xác định ngay khi khai báo.
Một khối nhớ liên tục được cấp phát cho một biến kiểu mảng.
Truy suất một phần tử: tên mảng[chỉ số]
Ví dụ mảng có n phần tử: a[0], a[1] a[n-1]
Phương pháp lập trình - Mảng, chuỗi
0 1 2 3 4 7 85 6 9
a
Khai báo mảng
Cú pháp
Ví dụ
int mangSoNguyen[10];
float mangSoThuc[100];
char chuoiKyTu[1000];
Lưu ý
Phải xác định cụ thể (hằng) khi khai báo.
Bộ nhớ sử dụng = *sizeof()
Một dãy liên tục có chỉ số từ 0 đến -1
Phương pháp lập trình - Mảng, chuỗi
[];
Ví dụ một số cách khai báo mảng
Phương pháp lập trình - Mảng, chuỗi
1. #define MAX 100
2. int main()
3. {
4. int A[MAX]; // Số phần tử là hằng
5. int B[100]; // Số phần tử là số nguyên cụ thể
6. float C[MAX];
7. float D[1000];
8. char E[MAX];
9. char F[10];
10.
11. typedef int mangSoNguyen[MAX];
12. typedef float mangSoThuc[100];
13. mangSoNguyen G;
14. mangSoThuc H, I;
15. . . .
16. return 0;
17.}
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
Nên sử dụng chỉ thị tiền xử lý #define để định nghĩa số
phần tử mảng
Phương pháp lập trình - Mảng, chuỗi
int n1 = 10;
int a[n1];
const int n2 = 20;
int b[n2];
#define n1 10
#define n2 20
int a[n1]; // int a[10];
float b[n2]; // float b[20];
Khởi tạo giá trị cho mảng lúc khai báo
Gồm các cách sau
Khởi tạo giá trị cho mọi phần tử của mảng
Khởi tạo giá trị cho một số phần tử đầu mảng
Phương pháp lập trình - Mảng, chuỗi
int a[4] = {2912, 1706, 1506, 1904};
2912 1706 1506 1904
0 1 2 3
a
int b[4] = {2912, 1706};
2912 1706 0 0
0 1 2 3
b
Khởi tạo giá trị cho mảng lúc khai báo
Gồm các cách sau
Khởi tạo giá trị 0 cho mọi phần tử của mảng
Tự động xác định số lượng phần tử
Phương pháp lập trình - Mảng, chuỗi
int a[4] = {0};
0 0 0 0
0 1 2 3
a
int a[] = {2912, 1706, 1506, 1904};
2912 1706 1506 1904
0 1 2 3
a
Truy xuất đến một phần tử
Thông qua chỉ số
Ví dụ
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ả không như mong muốn!
Phương pháp lập trình - Mảng, chuỗi
[]
int a[4];
a[0] = 8;
a[1] = 3;
a[2] = a[0] - 7;
a[3] = a[1] + a[2];
8 3 1 4
0 1 2 3
a
Gán dữ liệu kiểu mảng
Không được sử dụng phép gán thông thường mà phải gán
trực tiếp giữa các phần tử tương ứng
Ví dụ
Phương pháp lập trình - Mảng, chuỗi
= ; //sai
[] = ;
1. #define MAX 3
2. typedef int mangSo[MAX];
3. mangSo a = {1, 2, 3}, b;
4. b = a; // Sai
5. for (int i = 0; i < 3; i++)
6. b[i] = a[i];
Một số lỗi thường gặp
Khai báo không chỉ rõ số lượng phần tử
int a[]; => int a[100];
Số lượng phần tử liên quan đến biến hoặc hằng
int n1 = 10; int a[n1]; => int a[10];
const int n2 = 10; int a[n2]; => int a[10];
Khởi tạo cách biệt với khai báo
int a[4]; a = {2912, 1706, 1506, 1904};
=> int a[4] = {2912, 1706, 1506, 1904};
Chỉ số mảng không hợp lệ
int a[4];
a[-1] = 1; a[10] = 0;
Phương pháp lập trình - Mảng, chuỗi
Truyền mảng cho hàm
Truyền mảng cho hàm
Tham số kiểu mảng truyền cho hàm chính là địa chỉ của phần tử
đầu tiên của mảng
Bỏ số lượng phần tử hoặc sử dụng con trỏ.
Mảng có thể thay đổi nội dung sau khi thực hiện hàm.
Phương pháp lập trình - Mảng, chuỗi
void sapXepTang(int a[100]);
void sapXepTang(int a[]);
void sapXepTang(int *a);
Ví dụ truyền mảng cho hàm
Truyền mảng cho hàm
Gồm mảng và số lượng phần tử của mảng
Phương pháp lập trình - Mảng, chuỗi
1. void soPhanTu(int &n);
2. void nhapMang(int a[], int n);
3. void xuatMang(int a[], int n);
4. int main()
5. {
6. int a[100], n;
7. soPhanTu(n);
8. nhapMang(a, n);
9. xuatMang(a, n);
10.}
11.//. . .
Một số quy ước
Số lượng phần tử tối đa
Các hàm
Hàm void HoanVi(int &x, int &y): hoán vị giá trị của hai số
nguyên.
Hàm int LaSNT(int n): kiểm tra một số có phải là số nguyên tố.
Trả về 1 nếu n là số nguyên tố, ngược lại trả về 0.
Phương pháp lập trình - Mảng, chuỗi
#define MAX 100
Thủ tục HoanVi & Hàm LaSNT
Phương pháp lập trình - Mảng, chuỗi
1. void HoanVi(int &x, int &y){
2. int tam = x; x = y; y = tam;
3. }
4. bool LaSNT(int n){
5. int i=2;
6. while(i<n){
7. if(n%i==0)
8. break;
9. else
10. i++;
11. }
12. if(i==n)
13. return true;
14. return false;
15.}
Một số bài toán cơ bản
Viết hàm thực hiện từng yêu cầu sau
1. Nhập số phần tử
2. Nhập mảng
3. Xuất mảng
4. Tìm kiếm một phần tử trong mảng
5. Trích xuất các phần tử trong mảng
6. Đếm/ tính tổng các phần tử trong mảng
7. Kiểm tra tính chất của mảng
8. Tách mảng / Gộp mảng
9. Sắp xếp mảng giảm dần/tăng dần
10. Thêm/Xóa/Sửa một phần tử vào mảng
Phương pháp lập trình - Mảng, chuỗi
Hàm Nhập số phần tử của mảng
Phương pháp lập trình - Mảng, chuỗi
1. void soPhanTu(int &n)
2. {
3. do{
4. printf(“Nhap so luong phan tu: ”);
5. scanf(“%d”, &n);
6. }while(!(n>0 && n<=MAX));
7. }
Số phần tử của mảng nằm trong khoảng [1..MAX]
Hàm Nhập Mảng
Phương pháp lập trình - Mảng, chuỗi
1. void nhapMang(int a[], int n)
2. {
3. int i;
4. for (i = 0; i < n; i++)
5. {
6. printf(“Nhap phan tu thu %d: ”, i);
7. scanf(“%d”, &a[i]);
8. }
9. }
Nhập từng phần tử cho mảng
Phần tử của mảng có chỉ số từ 0 đến n-1
Hàm nhập mảng kết hợp
Phương pháp lập trình - Mảng, chuỗi
1. void nhapMang(int a[], int &n)
2. {
3. int i;
4. do{
5. printf(“Nhap so luong phan tu: ”);
6. scanf(“%d”, &n);
7. }while(nMAX);
8. for (i = 0; i < n; i++)
9. {
10. printf(“Nhap phan tu thu %d: ”, i);
11. scanf(“%d”, &a[i]);
12. }
13.}
Kết hợp nhập số phần tử và nhập giá trị của từng phần tử
Hàm Xuất Mảng
Phương pháp lập trình - Mảng, chuỗi
1. void xuatMang(int a[], int n)
2. {
3. printf(“Noi dung cua mang la: ”);
4. for (int i = 0; i < n; i++)
5. printf(“%d ”, a[i]);
6. printf(“\n”);
7. }
Xuất giá trị từng phần tử của mảng
Tìm kiếm một phần tử trong mảng
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 không tìm được thì trả về -1.
Phương pháp lập trình - Mảng, chuỗi
x
0 1 2 MAX - 1n - 1
a x b x
vị trí = 1
Hàm Tìm Kiếm
Phương pháp lập trình - Mảng, chuỗi
1. int TimKiem(int a[], int n, int x)
2. {
3. int viTri;
4. for (viTri = 0; viTri < n; viTri++)
5. if (a[viTri] == x)
6. return viTri;
7. return -1;
8. }
Hàm Tìm Kiếm (dùng while)
Phương pháp lập trình - Mảng, chuỗi
1. int TimKiem(int a[], int n, int x)
2. {
3. int vt = 0;
4. while (vt < n && a[vt] != x)
5. vt++;
6.
7. if (vt < n)
8. return vt;
9. else
10. return -1;
11.}
Tìm giá trị lớn nhất của mảng
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.
Phương pháp lập trình - Mảng, chuỗi
?max 78
0 1 2 MAX - 1n – 1
7 2 8 8
Hàm tìm Max
Phương pháp lập trình - Mảng, chuỗi
1. int timMax(int a[], int n)
2. {
3. int max = a[0];
4. for (int i = 1; i < n; i++)
5. if (a[i] > max)
6. max = a[i];
7. return max;
8. }
Hàm tìm vị trí của phần tử lớn nhất
Phương pháp lập trình - Mảng, chuỗi
1. int timVTMax(int a[], int n)
2. {
3. int vtMax = 0;
4. for (int i = 1; i < n; i++)
5. if (a[i] > a[vtMax])
6. vtMax = i;
7. return vtMax;
8. }
Trích xuất
Phương pháp lập trình - Mảng, chuỗi
Xuất ra màn hình các phần tử thỏa mãn điều kiện
Ví dụ: Xuất ra màn hình các phần tử là số nguyên tố
Ý tưởng
Lần lượt kiểm tra tất cả các phần tử,
Kiểm tra phần tử nào thỏa mãn điều kiện thì xuất ra màn hình.
1. void trichXuat(int a[], int n)
2. {
3. int i;
4. for (i = 0; i < n; i++)
5. if (laSNT(a[i]))
6. printf(“%d “, a[i]);
7. }
Đếm
Phương pháp lập trình - Mảng, chuỗi
Đếm các phần tử thỏa mãn điều kiện
Ví dụ: Đếm các phần tử là số nguyên tố
Ý tưởng
Lần lượt kiểm tra tất cả các phần tử,
Kiểm tra phần tử nào thỏa mãn điều kiện thì tăng biến đếm.
1. int demPT(int a[], int n)
2. {
3. int i, dem = 0;
4. for (i = 0; i < n; i++)
5. if (laSNT(a[i]))
6. dem++;
7. return dem;
8. }
Tính toán
Phương pháp lập trình - Mảng, chuỗi
Tính toán các phần tử thỏa mãn điều kiện
Ví dụ: Tính tổng các phần tử là số nguyên tố
Ý tưởng
Lần lượt kiểm tra tất cả các phần tử,
Kiểm tra phần tử nào thỏa mãn điều kiện thì cộng vào tổng.
1. void tinhTong(int a[], int n)
2. {
3. int i, tong = 0;
4. for (i = 0; i < n; i++)
5. if (laSNT(a[i]))
6. tong += a[i];
7. return tong;
8. }
Kiểm tra tính chất của mảng
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ố.
Phương pháp lập trình - Mảng, chuỗi
Hàm Kiểm Tra (Cách 1)
Phương pháp lập trình - Mảng, chuỗi
1. int KiemTra_C1(int a[], int n)
2. {
3. int dem = 0;
4. for (int i = 0; i < n; i++)
5. if (LaSNT(a[i]) == 1) // có thể bỏ == 1
6. dem++;
7. if (dem == n)
8. return 1;
9. return 0;
10.}
Hàm Kiểm Tra (Cách 2)
Phương pháp lập trình - Mảng, chuỗi
1. int KiemTra_C2(int a[], int n)
2. {
3. int dem = 0;
4. for (int i = 0; i < n; i++)
5. if (LaSNT(a[i]) == 0) // Có thể sử dụng !
6. dem++;
7. if (dem == 0)
8. return 1;
9. return 0;
10.}
Hàm Kiểm Tra (Cách 3)
Phương pháp lập trình - Mảng, chuỗi
1. int KiemTra_C3(int a[], int n)
2. {
3. for (int i = 0; i < n ; i++)
4. if (LaSNT(a[i]) == 0)
5. return 0;
6. return 1;
7. }
Tách các phần tử thỏa điều kiện
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.
Phương pháp lập trình - Mảng, chuỗi
Hàm Tách Số Nguyên Tố
Phương pháp lập trình - Mảng, chuỗi
1. void TachSNT(int a[], int na, int b[], int &nb)
2. {
3. nb = 0;
4.
5. for (int i = 0; i < na; i++)
6. if (LaSNT(a[i]) == 1)
7. {
8. b[nb] = a[i];
9. nb++;
10. }
11.}
Tách mảng thành 2 mảng con
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.
Phương pháp lập trình - Mảng, chuỗi
Hàm Tách 2 Mảng
Phương pháp lập trình - Mảng, chuỗi
1. void TachSNT2(int a[], int na,
2. int b[], int &nb, int c[], int &nc)
3. {
4. nb = 0;
5. nc = 0;
6. for (int i = 0; i < na; i++)
7. if (LaSNT(a[i]) == 1)
8. {
9. b[nb] = a[i]; nb++;
10. }
11. else
12. {
13. c[nc] = a[i]; nc++;
14. }
15.}
Gộp 2 mảng thành một mảng
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
Phương pháp lập trình - Mảng, chuỗi
Hàm Gộp Mảng
Phương pháp lập trình - Mảng, chuỗi
1. void GopMang(int a[], int na, int b[], int nb,
2. int c[], int &nc)
3. {
4. nc = 0;
5. for (int i = 0; i < na; i++)
6. {
7. c[nc] = a[i]; nc++; // c[nc++] = a[i];
8. }
9. for (int i = 0; i < nb; i++)
10. {
11. c[nc] = b[i]; nc++; // c[nc++] = b[i];
12. }
13.}
Sắp xếp mảng thành tăng dần
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ự).
Phương pháp lập trình - Mảng, chuỗi
0 1 2 MAX - 1n – 1
5 1 8 6
tạm 5
i j
8
1 5
j j
6 8
j
Hàm Sắp Xếp Tăng
Phương pháp lập trình - Mảng, chuỗi
1. void SapXepTang(int a[], int n)
2. {
3. int i, j;
4.
5. for (i = 0; i < n – 1; i++)
6. {
7. for (j = i + 1; j < n; j++)
8. {
9. if (a[i] > a[j])
10. HoanVi(a[i], a[j]);
11. }
12. }
13.}
Thêm một phần tử vào mả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ị.
Phương pháp lập trình - Mảng, chuỗi
c z
0 1 2 MAX - 1n – 1
a b
x chèn?
vt
n3
Hàm Thêm
Phương pháp lập trình - Mảng, chuỗi
1. void Them(int a[], int &n, int vt, int x)
2. {
3. if (vt >= 0 && vt <= n)
4. {
5. for (int i = n; i > vt; i--)
6. a[i] = a[i - 1];
7.
8. a[vt] = x;
9. n++;
10. }
11.}
Xóa một phần tử trong mảng
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ị.
Phương pháp lập trình - Mảng, chuỗi
b
0 1 2 MAX - 1n – 1
a x z
xóa?
vt
n - 1
Hàm Xóa
Phương pháp lập trình - Mảng, chuỗi
1. void Xoa(int a[], int &n, int vt)
2. {
3. if (vt >= 0 && vt < n)
4. {
5. for (int i = vt; i < n – 1; i++)
6. a[i] = a[i + 1];
7.
8. n--;
9. }
10.}
Bài tập thực hành
1. Các thao tác nhập xuất
a. Nhập mảng
b. Xuất mảng
2. Các thao tác kiểm tra
a. Mảng có phải là mảng toàn chẵn
b. Mảng có phải là mảng toàn số nguyên tố
c. Mảng có phải là mảng tăng dần
Phương pháp lập trình - Mảng, chuỗi
Bài tập thực hành
3. Các thao tác tính toán
a. Có bao nhiêu số chia hết cho 4 nhưng không chia hết cho 5
b. Tổng các số nguyên tố có trong mảng
4. Các thao tác tìm kiếm
a. Vị trí cuối cùng của phần tử x trong mảng
b. Vị trí số nguyên tố đầu tiên trong mảng nếu có
c. Tìm số nhỏ nhất trong mảng
d. Tìm số dương nhỏ nhất trong mảng
Phương pháp lập trình - Mảng, chuỗi
Bài tập thực hành
5. Các thao tác xử lý
a. Tách các số nguyên tố có trong mảng a đưa vào mảng b.
b. Tách mảng a thành 2 mảng b (chứa các số nguyên dương) và
c (chứa các số còn lại)
c. Sắp xếp mảng giảm dần
d. Sắp xếp mảng sao cho các số dương đứng đầu mảng giảm
dần, kế đến là các số âm tăng dần, cuối cùng là các số 0.
Phương pháp lập trình - Mảng, chuỗi
Bài tập thực hành
6. Các thao tác thêm/xóa/sửa
a. Sửa các số nguyên tố có trong mảng thành số 0
b. Chèn số 0 đằng sau các số nguyên tố trong mảng
c. Xóa tất cả số nguyên tố có trong mảng
Phương pháp lập trình - Mảng, chuỗi
Ngôn ngữ lập trình C
Chuỗi ký tự
Khái niệm Chuỗi
Phương pháp lập trình - Mảng, chuỗi
Mảng kiểu ký tự
char word [] = {'H','e','l','l','o','!'};
Chuỗi ký tự
char word [] = {'H','e','l','l','o','!','\0'};
char word [] = "Hello!";
Chuỗi ký tự bao gồm một ký tự đặc biệt nằm cuối chuỗi
Báo hiệu kết thúc chuỗi
Được hiểu là ký tự NULL, có thể viết là '\0'
Một chuỗi, ví dụ "Hello!", đã bao hàm ký tự kết thúc, tức
char[7]
Kiểu liệt kê, ví dụ {'H','e','l','l','o','!','\0'}, tức char[7]
Khai báo
Phương pháp lập trình - Mảng, chuỗi
Cú pháp char [] = ;
Cần xác định kích cỡ của chuỗi
Khai báo
Khởi tạo một giá trị cho biến
cần đủ lớn để chứa
có thể lớn hơn chiều dài của
bao gồm các ký tự và ký tự NULL (\0)
Nếu không khai báo (để trống)
Cần khởi tạo chuỗi ban đầu cho biến
Kích cỡ của biến chính là chiều dài của chuỗi (gồm ký tự NULL)
khởi tạo hợp lệ?
nằm giữa dấu hai nháy “”
liệt kê {} các ký tự bao gồm ký tự NULL, ‘\0’, ở cuối cùng
Ví dụ khai báo
Phương pháp lập trình - Mảng, chuỗi
1. char hello[] = "Hello!"; // char[7]
2. char hi[] = {'H','i','!','\0'}; // char[4]
3. char name[10];
4. char classname[20] = " Lop tin hoc ";
5. char city[20] = "TP. HCM";
6. char empty[] = "";
7. char empty1[10] = "";
8. char country[] = {'V','N'};// Array, not string!
9. char gender[2] = "male";// Error!? Overflow
10. char classroom = "V10.4";// Error!? Char vs string
11. char university[] = 'IUH';// Error!? Char vs string
12. char a[]; // Error!? unknown size
Khởi tạo giá trị
Phương pháp lập trình - Mảng, chuỗi
Một khởi tạo giá trị: char hello[] = "Hello!";
Tương đương với
char hello[] = {'H','e','l','l','o','!','\0'};
char hello[7] = {'H','e','l','l','o','!','\0'};
char hello[7] = "Hello!";
Một khởi tạo giá trị: char empty[] = "";
Tương đương với
char empty[] = {'\0'};
char empty[1] = {'\0'};
char empty[1] = "";
Khởi tạo giá trị (2)
Phương pháp lập trình - Mảng, chuỗi
Một khởi tạo giá trị:
char hi[7] = "Hi!";
char hi[7] = {'H','i','!','\0'};
Khởi tạo một chuỗi rất dài, dùng dấu \ để xuống dòng
char longstring[] = "Toi la sinh vien Cong nghe Thong
\
tin\nTruong Dai hoc Cong Nghiep TP. HCM.\n\
Than chao cac ban!";
char longstring[] = "Toi la sinh vien Cong nghe Thong
"
"tin\nTruong Dai hoc Cong Nghiep TP. HCM.\n"
"Than chao cac ban!";
0 1 2 3 4 5 6
'H 'i' '!' '\0'
Phép gán
Phương pháp lập trình - Mảng, chuỗi
Các phép gán trực tiếp cho chuỗi bị hạn chế
Bởi trình biên dịch xử lý với chuỗi như mảng
Một khai báo
char name[10];
name = "Quang"; // Error!
const char[6] không gán được cho char[10]
name = hello; // Error!
char[7] không gán được cho char[10]
Làm thế nào để thay đổi giá trị của chuỗi?
Dùng các hàm xử lý chuỗi như scanf, gets
Thay đổi từng phần tử
Các hàm trong thư viện string.h
Tự viết hàm xử lý chuỗi ký tự
Nhập chuỗi từ bàn phím
Phương pháp lập trình - Mảng, chuỗi
Dùng hàm scanf trong thư viện stdio.h
scanf("%s",name);
Nhập "My name is C", name = "My"
scanf("%[^\n]s",name);
Nhập "My name is C", name = "My name is C"
scanf tự động thêm ký tự NULL vào sau chuỗi nhận được từ
bàn phím
Dùng hàm gets trong thư viện stdio.h
gets(name);
Hàm gets tự động chấp nhận chuỗi có khoảng trắng
Phần tử của chuỗi
Phương pháp lập trình - Mảng, chuỗi
Phép khởi tạo char hello[] = "Hello!";
hello[0] = 'H', hello[1] = 'e', hello[2] = 'l', hello[6] = '\0'
Phép gán sau đó hello = "Hi!"; sẽ bị báo lỗi!
Có thể thay thế phép gán trên bằng các lệnh:
hello[0] = 'H';
hello[1] = 'i';
hello[2] = '!';
hello[3] = '\0';
Xuất chuỗi: printf("%s", hello);
printf("%s", "e"); // "e"= {'e', '\0'}
Xuất ký tự: printf("%c", hello[1]);
printf("%c", 'e');
hello[0] hello[1] hello[2] hello[3] hello[4] hello[5] hello[6]
'H' 'e' 'l' 'l' 'o' '!' '\0'
Thư viện string.h
Phương pháp lập trình - Mảng, chuỗi
size_t strlen(const char * str)
Trả về chiều dài của chuỗi ký tự str
strlen(“hello”) = 5, strlen(hello) = 6
size_t: Unsigned integral type
const char: Bởi hàm không thay đổi giá trị của str
char * strcpy(char * destination, const char * source)
Chép nội dung chuỗi source sang chuỗi destination bao gồm ký tự
NULL
Chuỗi destination phải đủ chứa chuỗi source (bao gồm ký tự NULL)
Bản thân hàm trả về destination
strcpy(hello, “Hi!”) trả về chuỗi “Hi!” và hello = “Hi!”
char * destination: Hàm thay đổi giá trị của destination
const char * source: Hàm không thay đổi giá trị của source
Thư viện string.h (2)
Phương pháp lập trình - Mảng, chuỗi
int strcmp( const char * str1, const char * str2 )
So sánh chuỗi str1 với chuỗi str2, so sánh từng ký tự từ đầu đến
khi phát hiện điểm khác nhau hoặc đến cuối chuỗi (‘\0’)
Giá trị trả về >0: str1 > str2
Giá trị trả về =0: str1 = str2
Giá trị trả về <0: str1 < str2
char * strcat( char * destination, const char * source )
Nối chuỗi source vào cuối chuỗi destination
destination phải đủ chứa chuỗi kết quả (bao gồm ký tự NULL)
char name[10]; strcpy(name, hello); strcat(name, hi); // name =
“Hello!Hi!”
Thư viện string.h (6)
Phương pháp lập trình - Mảng, chuỗi
char * strtok( char * str, const char * delimiters): Chia chuỗi
thành các chuỗi con
Char classname[20] = “ Lop tin:11”;
printf("%s\n",strtok(classname," :")); // “Lop”
printf("%s\n",strtok(NULL," :")); // “Tin”
printf("%s\n",strtok(NULL," :")); // “11”
void * memset( void * ptr, int value, size_t num): Điền giá trị
value vào num bytes ô nhớ đầu tiên của biến ptr
memset(hello,'2',2); // hello = “22llo!”
void * memcpy( void * destination, const void * source, size_t
num ): Chép num ô nhớ đầu tiên của biến source vào biến
destination
memcpy(hello,hi,3);// hello = “Hi!lo!”
Chuyển đổi giữa chuỗi và số
Phương pháp lập trình - Mảng, chuỗi
Thư viện chứa các hàm chuyển đổi giữa chuỗi và số
int atoi (const char * str)
Chuyển chuỗi str sang số nguyên và trả về giá trị số nguyên
atoi("34.5 53") = 34
double atof (const char* str)
Chuyển đổi một chuỗi sang kiểu số thực và trả về số thực
atof("34.5 53") = 34.5
long int atol ( const char * str )
Chuyển đổi chuỗi sang kiểu long int (4 bytes)
long long int atoll ( const char * str )
Chuyển đổi chuỗi sang kiểu long long int (8 bytes)
Chiều dài của chuỗi
Phương pháp lập trình - Mảng, chuỗi
Chiều dài của chuỗi được xác định dựa vào ký tự NULL, kết
thúc chuỗi
Viết hàm tính chiều dài của chuỗi
Hàm có kiểu nguyên, trả về chiều dài của chuỗi (output)
Đối số của hàm là một chuỗi (input)
Mã giả:
Khai báo một biến đếm và khởi tạo giá trị 0
Duyệt và đếm các phần tử của chuỗi
Dừng đếm khi gặp ký tự ‘\0’
Trả về chiều dài của chuỗi dựa vào giá trị của biến đếm
Tương tự hàm strlen của thư viện string.h
Ví dụ tham khảo hàm tính chiều dài của chuỗi
Phương pháp lập trình - Mảng, chuỗi
1. int stringLength(const char str[])
2. {
3. int count = 0;
4. while (str[count] != '\0')
5. count++;
6. return count;
7. }
8.
9. int main()
10.{
11. char hello[] = "Hello!";
printf("%d",stringLength(hello));
12.}
Chép chuỗi
Phương pháp lập trình - Mảng, chuỗi
Viết hàm chép nội dung của một chuỗi nguồn vào một chuỗi
đích
Chuỗi đích sẽ mang giá trị của chuỗi nguồn (output)
Đối số của hàm là hai chuỗi, nguồn và đích (input)
Mã giả
Khai báo một biến chạy và khởi gán giá trị ban đầu
Duyệt từng phần tử của chuỗi nguồn
Gán giá trị của từng phần tử ở chuỗi nguồn sang chuỗi đích
Dừng sao chép khi gặp ký tự ‘\0’
Gán ký tự ‘\0’ vào cuối chuỗi đích
Tương tự lệnh strcpy của thư viện string.h
Hàm có kiểu trả về là void
Bạn có thể trả về chuỗi đích cho hàm nếu biết dùng con trỏ, pointer (sẽ
học sau)
Ví dụ tham khảo hàm chép chuỗi
Phương pháp lập trình - Mảng, chuỗi
1. void stringCopy(char str1[], const char str2[])
2. {
3. int i=-1;
4. do{
5. i++;
6. str1[i]=str2[i];
7. }while (str2[i]!='\0');
8. }
9. int main()
10. {
11. char hello[10];
12. stringCopy(hello,"Hello!");
13. printf("%s",hello);
14. }
Nối chuỗi
Phương pháp lập trình - Mảng, chuỗi
Viết hàm nối một chuỗi nguồn vào cuối một chuỗi đích
Chuỗi đích sẽ mang giá trị là kết quả của việc nối hai chuỗi
Đối số của hàm gồm hai chuỗi
Mã giả
Khai báo hai biến chạy và khởi gán giá trị ban đầu
Biến chạy cho chuỗi nguồn, bắt đầu từ đầu chuỗi nguồn
Biến chạy cho chuỗi đích, bắt đầu từ cuối chuỗi đích
Duyệt từng phần tử của chuỗi nguồn
Gán giá trị của các phần tử của chuỗi nguồn vào chuỗi đích
Dừng sao chép khi gặp ký tự NULL của chuỗi nguồn
Gán ký tự NULL vào chuỗi đích
Hàm tương tự như hàm strcpy trong thư viện string.h
Ví dụ tham khảo hàm nối chuỗi
Phương pháp lập trình - Mảng, chuỗi
1. void stringAppend(char dest[], const char src[])
2. {
3. int i = stringLength(dest)-1, j = -1;
4. do{
5. i++;j++;
6. dest[i]=src[j];
7. }while(src[j]!='\0');
8. }
9. int main()
10. {
11. char thanks[20] = "Thank";
12. stringAppend(thanks, " you!");
13. printf("%s",thanks);
14. }
So sánh chuỗi
Phương pháp lập trình - Mảng, chuỗi
Viết hàm so sánh hai chuỗi ký tự str1 và str2
Hàm trả về giá trị
< 0 nếu str1 < str2
= 0 nếu str1 = str2
> 0 nếu str1 > str2
Hàm có 2 đối số là hai chuỗi cần so sánh
Mã giả
Khai báo và khởi tạo cho một biến chạy
Duyệt các phần tử cho đến khi
Gặp phần tử khác nhau
Hoặc kết thúc một trong hai chuỗi
So sánh phần tử cuối cùng và trả về giá trị so sánh tương ứng
Ví dụ tham khảo về hàm so sánh chuỗi
Phương pháp lập trình - Mảng, chuỗi
1. int stringCompare(const char str1[], const char
str2[])
2. {
3. int i = 0;
4. while(str1[i]==str2[i]&&str1[i]!='\0'&&str2[i]!='\0
')
5. i++;
6. if(str1[i]>str2[i])
7. return 1;
8. else if (str1[i]<str2[i])
9. return -1;
10. else
11. return 0;
12. };
Tìm kiếm
Phương pháp lập trình - Mảng, chuỗi
Viết hàm tìm kiếm vị trí của một chuỗi nguồn trong chuỗi
đích
Hàm trả về số nguyên là vị trí đầu tiên tìm thấy
Hàm trả về số âm nếu không tìm thấy
Đối số của hàm là hai chuỗi
Mã giả?
?
?
?
?
Ví dụ tham khảo về tìm kiếm chuỗi
Phương pháp lập trình - Mảng, chuỗi
Hoạt
động??
1. int stringSearch(const char str1[], const char
str2[])
2. {
3. int i=0, j=0;
4. while(str1[i]!='\0' && str2[j]!='\0')
5. {
6. if(str1[i+j]!=str2[j])
7. {
8. i++; j=0;
9. }
10. else
11. j++;
12. if (str2[j]=='\0')
13. return i;
14. }
15. return -1;
16. }
Hết
Phương pháp lập trình - Mảng, chuỗi
Khái niệm chuỗi
Khai báo, khởi tạo
Phần tử của chuỗi
Thư viện string.h
Thư viện stdlib.h
Một vài bài toán về
chuỗi
Bài tập về nhà
Nhập vào họ và tên, đếm số ký tự alphabet
Ví dụ: Nhập “Tran Van An ”, xuất ra có 9 ký
tự
Nhập vào một chuỗi, đếm số chữ
Ví dụ: Nhập “Day la mot chuoi ky tu”, xuất
ra có 6 chữ
Nhập vào họ và tên, xuất ra họ, chữ đệm và
tên
Ví dụ: Nhập “Tran Van An”, xuất ra họ Tran,
chữ đệm Van, tên An
Nhập vào một số, xuất ra chữ viết của số đó
Ví dụ: Nhập 456, xuất ra: Bon tram nam
muoi sau
Các file đính kèm theo tài liệu này:
- bai_giang_phuong_phap_lap_trinh_ts_ngo_huu_dung_6_phuong_phap_lap_trinh_mang_chuoi_3889_1985352.pdf