Bài giảng Phương pháp lập trình - Bài 6: Mảng một chiều, chuỗi - Ngô Hữu Dũng

pdf 73 trang ngocly 15/05/2021 1140
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Phương pháp lập trình - Bài 6: 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

Tài liệu đính kèm:

  • pdfbai_giang_phuong_phap_lap_trinh_bai_6_mang_mot_chieu_chuoi_n.pdf

Nội dung text: Bài giảng Phương pháp lập trình - Bài 6: Mảng một chiều, chuỗi - Ngô Hữu Dũng

  1. TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP THÀNH PHỐ HỒ CHÍ MINH Phương pháp lập trình Mảng một chiều, chuỗi TS. Ngô Hữu Dũng
  2. Đặ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ử 0 1 2 3 4 5 6 7 8 9 Phương pháp lập trình - Mảng, chuỗi
  3. 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] 0 1 2 3 4 5 6 7 8 9 a Phương pháp lập trình - Mảng, chuỗi
  4. 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
  5. Ví dụ một số cách khai báo mảng 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.} Phương pháp lập trình - Mảng, chuỗi
  6. 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 int n1 = 10; int a[n1]; const int n2 = 20; int b[n2];  Nên sử dụng chỉ thị tiền xử lý #define để định nghĩa số phần tử mảng #define n1 10 #define n2 20 int a[n1]; //  int a[10]; float b[n2]; //  float b[20]; Phương pháp lập trình - Mảng, chuỗi
  7. 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 int a[4] = {2912, 1706, 1506, 1904}; 0 1 2 3 a 2912 1706 1506 1904  Khởi tạo giá trị cho một số phần tử đầu mảng int b[4] = {2912, 1706}; 0 1 2 3 b 2912 1706 0 0 Phương pháp lập trình - Mảng, chuỗi
  8. 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 int a[4] = {0}; 0 1 2 3 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 a 2912 1706 1506 1904 Phương pháp lập trình - Mảng, chuỗi
  9. Truy xuất đến một phần tử  Thông qua chỉ số [ ]  Ví dụ int a[4]; 0 1 2 3 a[0] = 8; a 8 3 1 4 a[1] = 3; a[2] = a[0] - 7; a[3] = a[1] + a[2];  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
  10. 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 = ; //sai [ ] = ;  Ví dụ 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]; Phương pháp lập trình - Mảng, chuỗi
  11. 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
  12. 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. void sapXepTang(int a[100]); void sapXepTang(int a[]); void sapXepTang(int *a); Phương pháp lập trình - Mảng, chuỗi
  13. 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 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.//. . . Phương pháp lập trình - Mảng, chuỗi
  14. Một số quy ước  Số lượng phần tử tối đa #define MAX 100  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
  15. Thủ tục HoanVi & Hàm LaSNT 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.} Phương pháp lập trình - Mảng, chuỗi
  16. 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
  17. Hàm Nhập số phần tử của mảng  Số phần tử của mảng nằm trong khoảng [1 MAX] 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. } Phương pháp lập trình - Mảng, chuỗi
  18. Hàm Nhập Mảng  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 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. } Phương pháp lập trình - Mảng, chuỗi
  19. Hàm nhập mảng kết hợp  Kết hợp nhập số phần tử và nhập giá trị của từng phần tử 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(n MAX); 8. for (i = 0; i < n; i++) 9. { 10. printf(“Nhap phan tu thu %d: ”, i); 11. scanf(“%d”, &a[i]); 12. } 13.} Phương pháp lập trình - Mảng, chuỗi
  20. Hàm Xuất Mảng  Xuất giá trị từng phần tử của mảng 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. } Phương pháp lập trình - Mảng, chuỗi
  21. 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. x vị trí = 1 0 1 2 n - 1 MAX - 1 a x b x Phương pháp lập trình - Mảng, chuỗi
  22. Hàm Tìm Kiếm 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. } Phương pháp lập trình - Mảng, chuỗi
  23. Hàm Tìm Kiếm (dùng while) 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.} Phương pháp lập trình - Mảng, chuỗi
  24. 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. max 78? 0 1 2 n – 1 MAX - 1 7 2 8 8 Phương pháp lập trình - Mảng, chuỗi
  25. Hàm tìm Max 1. int timMax(int a[], int n) 2. { 3. int max = a[0]; 4. for (int i = 1; i max) 6. max = a[i]; 7. return max; 8. } Phương pháp lập trình - Mảng, chuỗi
  26. Hàm tìm vị trí của phần tử lớn nhất 1. int timVTMax(int a[], int n) 2. { 3. int vtMax = 0; 4. for (int i = 1; i a[vtMax]) 6. vtMax = i; 7. return vtMax; 8. } Phương pháp lập trình - Mảng, chuỗi
  27. Trích xuất  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. } Phương pháp lập trình - Mảng, chuỗi
  28. Đếm  Đế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. } Phương pháp lập trình - Mảng, chuỗi
  29. Tính toán  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. } Phương pháp lập trình - Mảng, chuỗi
  30. 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
  31. Hàm Kiểm Tra (Cách 1) 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.} Phương pháp lập trình - Mảng, chuỗi
  32. Hàm Kiểm Tra (Cách 2) 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.} Phương pháp lập trình - Mảng, chuỗi
  33. Hàm Kiểm Tra (Cách 3) 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. } Phương pháp lập trình - Mảng, chuỗi
  34. 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
  35. Hàm Tách Số Nguyên Tố 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.} Phương pháp lập trình - Mảng, chuỗi
  36. 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
  37. Hàm Tách 2 Mảng 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.} Phương pháp lập trình - Mảng, chuỗi
  38. 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
  39. Hàm Gộp Mảng 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.} Phương pháp lập trình - Mảng, chuỗi
  40. 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ự). tạm 58 0 1 2 n – 1 MAX - 1 51 15 86 68 i j j j j Phương pháp lập trình - Mảng, chuỗi
  41. Hàm Sắp Xếp Tăng 1. void SapXepTang(int a[], int n) 2. { 3. int i, j; 4. 5. for (i = 0; i a[j]) 10. HoanVi(a[i], a[j]); 11. } 12. } 13.} Phương pháp lập trình - Mảng, chuỗi
  42. 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ị. x chèn? 0 1 2 3 n – 1 n MAX - 1 a b c z vt Phương pháp lập trình - Mảng, chuỗi
  43. Hàm Thêm 1. void Them(int a[], int &n, int vt, int x) 2. { 3. if (vt >= 0 && vt vt; i ) 6. a[i] = a[i - 1]; 7. 8. a[vt] = x; 9. n++; 10. } 11.} Phương pháp lập trình - Mảng, chuỗi
  44. 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ị. xóa? 0 1 2 n - 1 n – 1 MAX - 1 a x b z vt Phương pháp lập trình - Mảng, chuỗi
  45. Hàm Xóa 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.} Phương pháp lập trình - Mảng, chuỗi
  46. 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
  47. 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
  48. 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
  49. 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
  50. Ngôn ngữ lập trình C Chuỗi ký tự
  51. Khái niệm 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] Phương pháp lập trình - Mảng, chuỗi
  52. Khai báo  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 Phương pháp lập trình - Mảng, chuỗi
  53. Ví dụ khai báo 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 Phương pháp lập trình - Mảng, chuỗi
  54. Khởi tạo giá trị  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] = ""; Phương pháp lập trình - Mảng, chuỗi
  55. Khởi tạo giá trị (2)  Một khởi tạo giá trị:  char hi[7] = "Hi!"; 0 1 2 3 4 5 6  char hi[7] = {'H','i','!','\'H'0'};'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!"; Phương pháp lập trình - Mảng, chuỗi
  56. Phép gán  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ự Phương pháp lập trình - Mảng, chuỗi
  57. Nhập chuỗi từ bàn phím  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ương pháp lập trình - Mảng, chuỗi
  58. Phần tử của 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[0] hello[1] hello[2] hello[3] hello[4] hello[5] hello[6]  hello[1] = 'i'; 'H' 'e' 'l' 'l' 'o' '!' '\0'  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'); Phương pháp lập trình - Mảng, chuỗi
  59. Thư viện string.h  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 Phương pháp lập trình - Mảng, chuỗi
  60. Thư viện string.h (2)  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!” Phương pháp lập trình - Mảng, chuỗi
  61. Thư viện string.h (6)  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!” Phương pháp lập trình - Mảng, chuỗi
  62. Chuyển đổi giữa chuỗi và số  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) Phương pháp lập trình - Mảng, chuỗi
  63. Chiều dài của 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 Phương pháp lập trình - Mảng, chuỗi
  64. Ví dụ tham khảo hàm tính chiều dài của 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.} Phương pháp lập trình - Mảng, chuỗi
  65. Chép 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) Phương pháp lập trình - Mảng, chuỗi
  66. Ví dụ tham khảo hàm chép 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. } Phương pháp lập trình - Mảng, chuỗi
  67. Nối 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 Phương pháp lập trình - Mảng, chuỗi
  68. Ví dụ tham khảo hàm nối 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. } Phương pháp lập trình - Mảng, chuỗi
  69. So sánh 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  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 Phương pháp lập trình - Mảng, chuỗi
  70. Ví dụ tham khảo về hàm so sánh 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. }; Phương pháp lập trình - Mảng, chuỗi
  71. Tìm kiếm  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ả?  ?  ?  ?  ? Phương pháp lập trình - Mảng, chuỗi
  72. Ví dụ tham khảo về tìm kiếm chuỗi 1. int stringSearch(const char str1[], const char  Hoạt str2[]) động?? 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. } Phương pháp lập trình - Mảng, chuỗi
  73. Hết  Bài tập về nhà  Khái niệm chuỗi  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ý  Khai báo, khởi tạo tự  Nhập vào một chuỗi, đếm số chữ  Phần tử của chuỗi  Ví dụ: Nhập “Day la mot chuoi ky tu”, xuất ra có 6 chữ  Thư viện string.h  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,  Thư viện stdlib.h chữ đệm Van, tên An  Nhập vào một số, xuất ra chữ viết của số đó  Một vài bài toán về  Ví dụ: Nhập 456, xuất ra: Bon tram nam chuỗi muoi sau Phương pháp lập trình - Mảng, chuỗi