Lập trình C Chương 1. Mảng một chiều (6 tiết)

Trần Minh Thái Email: minhthai@huflit.edu.vn Website: www.minhthai.edu.vn Cập nhật: 09/11/2016

1

Nội dung

1.

Khái niệm kiểu dữ liệu mảng một chiều

2.

Khai báo

3.

Các thao tác nhập/ xuất mảng

4.

Kỹ thuật tìm kiếm, liệt kê giá trị trong mảng

5.

Kỹ thuật xóa, chèn

6.

Chuỗi ký tự và các thao tác xữ lý cơ bản

2

3

KHÁI NIỆM VÀ KHAI BÁO

Khái niệm

̀

c  câ p  pha t  bô  nh   liên  tuc  và  bao  gô m

• Mang  đ ̀

ượ ́

́ ̀

́ ̀

nhiê u biê n tha nh phâ n

̀

̀

̀

̀

ế

́ • M i bi n tha nh phâ n co  cu ng KDL và cu ng tên

Giá trị

0

1

2

3

4

5

6

7

8

9

Vị trí

Vị trí được tính từ 0

4

̉ ̣ ̣

Khai báo

< Tên mảng > [< Số phần tử tối đa của mảng>] ;

Ví dụ int a[100]; //Khai bao mang so nguyen a toi da 100 phan tu float b[50]; //Khai bao mang so thuc b toi da 50 phan tu Nhằm thuận tiện cho việc viết chương trình, ta nên định nghĩa hằng char str[30]; //Khai bao mang ky tu str toi da 30 ky số MAX ở đầu chương trình – là kích thước tối đa của mảng - như tu sau:

#define MAX 100 int main() {

int a[MAX], b[MAX]; //Các lệnh return 0;

}

5

Khai báo, gán giá trị ban đầu

Gán từng phần tử

Giá trị

int a[5] = { 3, 6, 8, 1, 12 }; 6 1

8 2

1 3

3 0

Vị trí

12 4

Gán toàn bộ phần tử trong mảng có cùng giá trị

Giá trị

3 int a[8] = { 3 }; 0

3 1

Vị trí

3 2

3 3

3 4

3 5

3 6

3 7

6

Truy xuất giá trị

TênM ng [v  trí c n truy xu t]

int main()

Vị trí 3

{

int a[5] = { 3, 6, 8, 11, 12 };

printf("Gia tri mang tai vi tri 3 = ", a[3]);

getch();

return 0;

}

7

Kết quả: Gia tri mang tai vi tri 3 = 11

Các thao tác trên mảng

1. Nhập

2. Xuất (liệt kê)

3. Tìm kiếm

4. Đếm

5. Sắp xếp

6. Kiểm tra mảng thỏa điều kiện cho trước

7. Tách/ ghép mảng

8. Chèn / xóa

8

9

THAO TÁC NHẬP VÀ XUẤT

Nhập mảng

a[0]

a[1]

a[2]

a[3]

a[4]

a[5] … a[n- 1]

ậ ậ ậ

 Nh p ậ a[i], v i 0 ≤ i ≤ n­1

Nh p a[0] Nh p a[1] Nh p a[2] … Nh p a[n­1]

10

Ví dụ nhập và xuất mảng số nguyên

#define MAX 100 void NhapKichThuoc(int &n) {

printf("Nhap vao kich thuoc mang: "); scanf("%d", &n);

} void NhapMang(int a[], int n) {

for (int i = 0; i < n; i++) {

printf("* Nhap vao phan tu tai vi tri %d: ", i); scanf("%d", &a[i]);

}

11

}

void XuatMang(int a[], int n) {

for(int i=0; i

printf("%d\t", a[i]);

}

} int main() {

int a[MAX], n; NhapKichThuoc(n); NhapMang(a, n); printf("Cac gia tri trong mang a:\n"); XuatMang(a, n);

getch(); return 0;

}

12

Phát sinh ngẫu nhiên giá trị nguyên

• Sử dụng thư viện hàm

• Dùng hàm srand() trong hàm main() trước khi gọi hàm phát sinh:

để khởi tạo bộ giá trị ngẫu nhiên

• Dùng hàm rand()%k để phát sinh số ngẫu nhiên: có giá trị từ 0

đến k-1

13

Ví dụ: Chương trình tạo mảng số nguyên có giá trị ngẫu nhiên từ 1 đến MAX

#include #include #include #include #pragma warning(disable: 4996); #define MAX 100

void NhapKichThuoc(int &n); void PhatSinh(int a[], int n); void XuatMang(int a[], int n);

14

void NhapKichThuoc(int &n) {

printf("Nhap vao kich thuoc mang: "); scanf("%d", &n);

} void PhatSinh(int a[], int n) {

for (int i = 0; i < n; i++) {

a[i] = rand() % MAX + 1;

}

} void XuatMang(int a[], int n) {

for(int i=0; i

printf("%d\t", a[i]);

}

}

15

int main() {

int a[MAX], n; NhapKichThuoc(n); srand((unsigned int)time(NULL)); PhatSinh(a, n); printf("Cac gia tri trong mang a:\n"); XuatMang(a, n);

getch(); return 0;

}

16

Bài tập

Cho mảng một chiều số nguyên a, kích thước n. Hãy viết các hàm:

1.

Phát sinh giá trị các phần tử ngẫu nhiên theo thứ tự tăng dần cho a.

2.

Phát sinh giá trị các phần tử ngẫu nhiên có giá âm và dương.

17

18

XUẤT CÓ ĐIỀU KIỆN

Liệt kê các phần tử thỏa đk cho trước

Mẫu 1:

void LietKeXXX( a[], int n)

{

for (int i = 0; i

if (a[i] thỏa điều kiện)

Xuất a[i];

}

19

Liệt kê các phần tử thỏa đk cho trước

Mẫu 2:

void LietKeXXX( a[], int n, int x)

{

for (int i = 0; i

if (a[i] thỏa điều kiện so với x)

Xuất a[i];

}

20

Ví dụ 1: Liệt kê các phần tử có giá trị chẵn trong mảng số nguyên

void LietKeChan(int a[], int n)

{

for (int i = 0; i

if (a[i] %2 ==0)

printf(“%d\t”, a[i]);

}

Ví dụ 2: Liệt kê các phần tử có giá trị lớn hơn x trong mảng số nguyên

void LietKeLonHonX(int a[], int n, int x)

{

for (int i = 0; i

21

if (a[i] > x)

printf(“%d\t”, a[i]);

}

Ví dụ 3: Chương trình nhập vào mảng một chiều số nguyên a, kích thước n. In ra các phần tử có giá trị lớn hơn x có trong mảng #define MAX 100 void NhapKichThuoc(int &n); void NhapMang(int a[], int n); void XuatMang(int a[], int n); void LietKeLonHonX(int a[], int n, int x); void NhapKichThuoc(int &n) {

prinft(“Nhap vao kich thuoc mang: “); scanf(“%d”, &n);

} void NhapMang (int a[], int n) {

for (int i = 0; i < n; i ++) {

printf(“Nhap phan tu tai vi tri %d: “, i); scanf(“%d”, &a[i]);

22

}

}

void XuatMang (int a[], int n) {

for (int i = 0; i < n; i ++) printf(“%d\t”, a[i]);

} void LietKeLonHonX(int a[], int n, int x) {

for (int i = 0; i

if (a[i] > x)

printf(“%d\t”, a[i]);

}

23

int main() {

int a[MAX], n, x; NhapKichThuoc(n); NhapMang(a, n); printf("Cac phan tu cua mang:\n"); XuatMang(a, n); printf("Nhap gia tri x: “); scanf(“%d”, &x); printf("Cac phan tu co gia tri lon hon %d:\n", x);  LietKeLonHonX(a, n, x); getch(); return 0;

}

24

Bài tập tại lớp

1. Nhập vào kích thước mảng (0

2. Nhập các giá trị vào mảng một chiều a

3. Xuất các phần tử là bội số của 5 trong mảng a

4. Xuất các phần tử là số nguyên tố trong mảng a

5. Hàm main() để gọi thực hiện các yêu cầu từ 1

Cho mảng số nguyên a, gồm n phần tử, viết chương trình gồm các hàm thực hiện các yêu cầu sau:

25

đến 4

26

THAO TÁC ĐẾM SỐ LƯỢNG

Đếm số lượng phần tử

Mẫu 1:

int DemXXX( a[], int n)

{

int d = 0;

for (int i = 0; i

if (a[i] thỏa điều kiện)

d++;

return d;

27

}

Mẫu 2:

int DemXXX( a[], int n, int x)

{

int d = 0;

for (int i = 0; i

if (a[i] thỏa điều kiện so với x)

d++;

return d;

28

}

Ví dụ 1: Đếm các phần tử có giá trị là số nguyên tố trong mảng số nguyên

int DemSNT(int a[], int n) {

int d = 0;

for (int i = 0; i

29

int LaSNT(int k) { int d = 0; for (int i = 1; i <= k; i++) { if (k % i == 0) { d++; } } if(d == 2) return 1; return 0; }

Ví dụ 2: Đếm các phần tử có giá trị nhỏ hơn x trong mảng số nguyên

int DemNhoHonX(int a[], int n, int x)

{

int d = 0;

for (int i = 0; i

if (a[i] < x)

d++;

return d;

}

30

ươ

ầ ử

ướ

ề ộ ả ng  trình  nh p  vào  m ng  m t  chi u  s   nguyên  a,  kích  ố ố ượ  là s  nguyên t

ậ ng các ph n t

có trong m ng

ụ Ví  d   3:  Ch ế th c n. Đ m s  l #define MAX 100 void NhapKichThuoc(int &n); void NhapMang(int a[], int n); void XuatMang(int a[], int n); int LaSNT(int k); int DemSNT(int a[], int n); void NhapKichThuoc(int &n){

prinft(“Nhap vao kich thuoc mang: “); scanf(“%d”, &n);

} void NhapMang (int a[], int n){ for (int i = 0; i < n; i ++) {

printf(“Nhap phan tu tai vi tri %d: “, i); scanf(“%d”, &a[i]);

}

}

31

void XuatMang (int a[], int n) {

for (int i = 0; i < n; i ++) printf(“%d\t”, a[i]);

}

int DemSNT(int a[], int n) {

int d = 0;

int d = 0;

for (int i = 0; i

int LaSNT(int k) { for (int i = 1; i <= k; i++) if (k % i == 0) d++; if (d == 2) return 1; return 0; }

32

int main() {

int a[MAX], n, kq; NhapKichThuoc(n); NhapMang(a, n); printf("Cac phan tu cua mang:\n"); XuatMang(a, n); kq = DemSNT(a, n); if(kq==0)

printf("Khong co so nguyen to trong mang“);

else

printf("So luong so nguyen to la: %d“, kq);

getch();        return 0; }

33

Bài tập

Cho mảng một chiều số nguyên a, kích thước n. Hãy viết các hàm:

1. Đếm số lượng các phần tử có giá trị lẻ.

2. Đếm những phần tử có giá trị là bội số của 3.

34

35

THAO TÁC TÌM KIẾM

Tìm phần tử x

• Ý tưởng

Lần lượt so sánh x với phần tử thứ nhất, thứ hai, ... của mảng a cho đến khi gặp được phần tử cần tìm, hoặc đã tìm hết mảng mà không thấy x

• Minh họa tìm x =10

10

Đã tìm Chưa hết thấy tại mảng vị trí 5

5 2

12 3

41 4

10 10 5

32 6

13 7

15 9

3 10

9 8

7 1

25

Đã hết Chưa hết mảng mảng

9 8

• Minh họa tìm x =25 41 5 4 2

12 3

7 1

10 5

32 6

13 7

15 9

3 10

36

Code minh họa tìm x trong mảng số nguyên

(nếu x không xuất hiện trong mảng trả về -1)

int TimVTX(int a[], int n, int x)

{

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

{

if (a[i] == x)

return i;

}

37

return -1;

}

Bài tập

Cho mảng một chiều số nguyên a, kích thước n. Viết các hàm sau:

1.

Tìm vị trí xuất hiện cuối cùng của phần tử có giá trị x nếu có.

2.

Tìm vị trí phần tử có giá trị âm xuất hiện đầu tiên trong mảng.

38

Tìm vị trí phần tử nhỏ nhất?

Giả sử cần tìm vị trí phần tử nhỏ nhất trong dãy số sau ?

15

10

9

7

5

1 2 3

3 4

5

1 6

7

2 8

39

Bước 1: Giả sử vị trí phần tử nhỏ nhất là 1 (vtmin), phần tử này có giá trị 10

vtmin

15

10

9

7

5

1 2 3

3 4

5

1 6

2 8

40

7

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin

vtmin

5 nhỏ hơn 10 nên cập nhật vị trí min

15

10

9

7

5

1 2 3

3 4

5

1 6

2 8

7 41

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin

vtmin

7 lớn hơn 5 nên không cập nhật vị trí min

15

10

9

7

5

1 2 3

3 4

5

1 6

2 8

7 42

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin

vtmin

3 nhỏ hơn 5 nên cập nhật vị trí min

15

10

9

7

5

1 2 3

3 4

5

1 6

2 8

7 43

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin

9 lớn hơn 3 nên không cập nhật vị trí min

vtmin

15

10

9

7

5

1 2 3

3 4

5

1 6

2 8

7 44

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì 1 nhỏ hơn 3 cập nhật lại vtmin nên cập nhật vị trí min

vtmin

15

10

9

7

5

1 2 3

3 4

5

1 6

2 8

7 45

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì 15 lớn hơn 1 cập nhật lại vtmin nên không cập nhật vị trí min

vtmin

15

10

9

7

5

1 2 3

3 4

5

1 6

2 8

7 46

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin

vtmin

2 lớn hơn 1 nên không cập nhật vị trí min

15

10

9

7

5

1 2 3

3 4

5

1 6

2 8

7 47

Code minh họa tìm vị trí phần tử có giá trị nhỏ nhất trong mảng số nguyên

int TimVTMin(int a[], int n)

{

int vtmin = 0;

for (int i = 1; i < n; i++)

{

if (a[i] < a[vtmin])

vtmin = i;

}

return vtmin;

48

}

Bài tập

ướ

ề ố Cho m ng m t chi u s  nguyên a, kích th

c n. Hãy

ế

vi

t  hàm:

1.

ầ ử

Tìm v  trí ph n t

ấ ị ớ  có giá tr  l n nh t

ầ ử ớ

2. Tìm giá tr  ph n t

ấ  l n nh t

ầ ử

ị 3. Tìm v  trí ph n t

ấ  có giá tr  âm l n nh t

49

50

THAO TÁC TÍNH TOÁN

Tính tổng, giá trị trung bình có điều kiện

Mẫu tính tổng:

TongXXX( a[], int n)

{

s = 0;

for (int i = 0; i

{

if (a[i] thỏa điều kiện)

s += a[i];

}

51

return s;

}

Mẫu tính trung bình:

float TrungBinhXXX( a[], int n)

{

s = 0;

int d = 0;

for (int i = 0; i

{

if (a[i] thỏa điều kiện)

{

s += a[i];

d ++;

}

}

if (d==0)

52

return 0;

return (float) s / d;

}

Ví dụ 1: Tính tổng các phần tử có giá trị lẻ trong mảng trong mảng số nguyên

int TongLe(int a[], int n)

{

int s = 0;

for (int i = 0; i

{

if (a[i] %2!=0)

s += a[i];

53

}

return s;

}

Ví dụ 2: Tính giá trị trung bình các phần tử có giá trị âm trong mảng số nguyên

float TrungBinhAm(int a[], int n)

{

long s = 0;

int d = 0;

for (int i = 0; i

{

if (a[i] < 0)

{

s += a[i];

d++;

}

54

}

if (d == 0)

return 0;

return (float)s / d;

}

55

SẮP XẾP MẢNG THEO THỨ TỰ

Mẫu phương thức sắp thứ tự tăng:

void SapTang( a[], int n)

{

for (int i = 0; i < n-1; i ++)

{

for(int j = i+1; j < n; j ++)

if (a[i] > a[j])

HoanVi(a[i], a[j]);

}

}

void HoanVi( &a, &b)

{

tam = a;

a = b;

56

b = tam;

}

57

THAO TÁC KIỂM TRA GIÁ TRỊ MẢNG CÓ THỎA ĐIỀU KIỆN

Kiểm tra tồn tại

Kiểm tra xem mảng có tồn tại một phần tử thỏa điều kiện nào đó cho trước hay không?

 tìm phần tử thỏa điều kiện để kết luận

Trả về:

• 1 nếu có phần tử thỏa điều kiện

• 0 nếu không có phần tử nào thỏa điều kiện

58

Kiểm tra tồn tại

int KiemTraTonTaiXXX( a[], int n)

{

for (int i = 0; i

if (a[i] thỏa điều kiện)

return 1;

return 0; //Không có phần tử nào thỏa điều kiện

}

59

Kiểm tra tồn tại

Kiểm tra xem mảng số nguyên có tồn tại số lẻ không?

int KiemTraTonTaiLe(int a[], int n)

{

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

if (a[i] % 2 != 0)

return 1;

return 0;

}

60

Kiểm tra với mọi phần tử

• Kiểm tra tất cả các phần tử thỏa điều kiện nào đó cho trước

 tìm phần tử không thỏa điều kiện để kết luận mảng không thỏa điều kiện

Trả về:

• 0 nếu gặp phần tử không thỏa điều kiện

• 1 nếu không có phần tử nào không thỏa điều kiện

61

ủ ị ủ ề ệ Tìm ph  đ nh c a đi u ki n cho tr c ướ  k t lu n  ậ 0 ế

Kiểm tra với mọi phần tử

int KiemTraXXX( a[], int n)

{

for (int i = 0; i

if (a[i] không thỏa điều kiện)

return 0;

return 1;

}

62

Kiểm tra với mọi phần tử

Kiểm tra xem mảng số nguyên có toàn bộ là giá trị âm không?

int KiemTraToanAm(int a[], int n)

{

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

if (a[i] >= 0)

return 0;

return 1;

}

63

Bài tập

Cho mảng số nguyên kích thước n. Viết các hàm sau:

1.

Kiểm tra xem mảng có chứa số nguyên tố không?

2.

Kiểm tra xem mảng có thứ tự tăng dần hay không?

3.

Kiểm tra xem mảng có chẵn lẻ xen kẽ không?

4.

Kiểm tra xem mảng có âm dương xen kẽ không?

64

1. Kiểm tra xem mảng có chứa số nguyên tố không?

/*Kiem tra k co phai la so nguyen to khong? * Neu la so nguyen to thi tra ve 1 * Nguoc lai tra ve 0 */ int LaSNT(int k); /*Kiem tra xem mang a co chua so nguyen to khong? * Neu co thi tra ve 1 * Nguoc lai tra ve 0 */ int CoTonTaiSNT(int a[], int n);

65

66

int LaSNT(int k) { int d=0; for(int i=1; i<=k; i++) { if(k%i==0) d++; } if(d==2) return 1; //La so nguyen to return 0; } int CoTonTaiSNT(int a[], int n) { for(int i=0; i

int main() { int a[MAX], n, kq; NhapKT(n); NhapMang(a, n); printf("Mang ban dau: "); XuatMang(a, n); kq=CoTonTaiSNT(a, n); if(kq==1) printf("Ton tai so nguyen to trong mang"); else printf("Khong ton tai so nguyen to trong mang");

getch(); return 0; }

67

2. Kiểm tra mảng có thứ tự tăng dần?

int LaTangDan(int a[], int n) { for(int i=0; i a[i + 1]) return 0; } return 1; }

68

3. Kiểm tra chẵn lẻ xen kẽ?

int LaChanLeXenKe(int a[], int n) { for(int i=0; i

69

4. Kiểm tra âm dương xen kẽ

int LaAmDuongXenKe(int a[], int n) { for (int i = 0; i < n - 1; i++) { if ((a[i] * a[i + 1]) >= 0) return 0; } return 1; }

70

71

THAO TÁC CHÈN

Chèn phần tử vào mảng

ả • Cho m ng sau:

12 0

5 1

7 2

9 3

21 4

38 5

• Hãy trình bày t ng b

ừ ướ ị ủ ả 111 vào v  trí 3 c a m ng

c chèn  111

12 0

5 1

9 3

21 4

38 5

7 2

72

72

Chèn phần tử vào mảng

12 5 7 9 21 38 5 0

1

2

3

4

6

1. Di chuy n a[5] sang a[6]:

a[6] = a[5]

12 5 7 9 21 4 2 0

1

3

5

38 6

2. Di chuy n a[4] sang a[5]:

a[5] = a[4]

12 5 7 9 3 1 0

2

4

21 38 6 5

3. Di chuy n a[3] sang a[4]:

a[4] = a[3]

12 5 7 2 1 0

3

9 4

21 38 6 5

4. Gán a[3] = 111

12 5 7 111 9 21 38 6 3 0

1

4

2

5

5. Tăng kích th

73

c ướ n++

ị ủ ả Chèn 111 vào v  trí 3 c a m ng

Chèn phần tử vào mảng

Gọi k là vị trí cần chèn, n là kích thước mảng, x là giá trị cần chèn

• a[6] = a[5]

• a[5] = a[4]

• a[4] = a[3]

i = n­1

• a[3] = 111

• n++

a[i+1]=a[i]

i = k

74

a[k]=x

Chèn phần tử vào mảng

ế

ầ ử

t hàm chèn ph n t

ướ

ố c  trong  m ng  s   nguyên  a  kích  th

có giá tr  x vào v  trí k  c  n  theo

BT: Hãy vi ướ cho  tr ẫ m u sau:

void ChenX(int a[], int &n, int x, int k);

75

75

Chèn phần tử vào mảng

void ChenX(int a[], int &n, int x, int k) { for(int i = n-1; i>=k; i--) { a[i+1] = a[i]; } a[k] = x; n++; }

76

Bài tập áp dụng

Hãy viết hàm chèn phần tử có giá trị x vào sau phần tử có giá trị nhỏ nhất có trong mảng số nguyên a, kích thước n (giả sử mảng không có giá trị trùng nhau)

Gợi ý:

1. Viết hàm tìm vị trí phần tử có giá trị nhỏ

nhất (min)

2. Viết hàm chèn x vào sau min (sử dụng

hàm ChenX)

77

77

Bài tập áp dụng

int TimVTMin(int a[], int n) { int vtmin = 0; for (int i = 1; i < n; i++) { if (a[i] < a[vtmin]) vtmin = i; } return vtmin; }

78

Bài tập áp dụng

void ChenXSauMin(int a[], int &n, int x) { int vt = TimVTMin(a, n); ChenX(a, n, x, vt + 1); }

79

80

THAO TÁC XÓA

Xóa phần tử khỏi mảng

ả • Cho m ng sau:

9 3

21 4

38 5

12 0

5 1

7 2

• Hãy trình bày t ng b trong m ngả

ừ ướ c xóa ph n t ầ ử ạ ị  t i v  trí 3

12 0

5 1

7 2

9 3

21 4

38 5

81

81

Xóa phần tử khỏi mảng

12 5 7 9 21 38 5 0

4

3

2

1

1. D i a[4] sang a[3]:

a[3] = a[4]

12 5 7 21 3 0

1

2

4

38 5

2. D i a[5] sang a[4]:

a[4] = a[5]

12 5 7 21 38 4 2 0

1

3

5

ướ

3. Gi m kích th

c 1 ph n t

ầ ử n­­ :

12 5 7 21 38 4 2 0

1

3

82

Xoá ph n t ầ ử ạ ị  t i v  trí 3

Xoá phần tử khỏi mảng

Gọi k là vị trí cần xoá, n là kích thước mảng

• a[3] = a[4]

• a[4] = a[5]

i=n­2

a[i]=a[i+1]

ướ

Gi m kích th

c 1 ph n t

ầ ử n­­ :

83

i=k

Xóa phần tử khỏi mảng

ế

ướ

c

t  hàm  xóa  ph n  t BT:  Hãy  vi ố trong m ng s  nguyên a kích th

ầ ử ạ ị i  v   trí  k  cho  tr   t ẫ ướ c n theo m u sau:

void XoaTaiVTk(int a[], int &n, int k);

84

84

Xóa phần tử khỏi mảng

void XoaTaiVTk(int a[], int &n, int k) { for (int i = k; i <= n - 2; i++) { a[i] = a[i + 1]; } n--; }

85

Bài tập áp dụng

Hãy viết hàm xóa phần tử x (nếu có) trong mảng số nguyên a, kích thước n (giả sử mảng không có giá trị trùng nhau)

Gợi ý:

1. Viết hàm tìm vị trí phần tử có giá trị x

2. Viết hàm xoá phần tử x (sử dụng hàm

XoaTaiVTk)

86

86

Bài tập áp dụng

87

int TimVTX(int a[], int n, int x) { for (int i = 0; i < n; i++) { if (a[i] == x) return i; } return -1; }

Bài tập áp dụng

88

void XoaX(int a[], int &n, int x) { int vt = TimVTX(a, n, x); if (vt != -1) { XoaTaiVTk(a, n, vt); } }

89

CHUỖI KÝ TỰ

Khái niệm

́ ự ườ ặ ợ ệ ủ ả ̃ • Chuô i  ky   t là  tr ng  h p  đ c  bi t  c a  m ng  1

́ ̀ ̃ ̀ ̀ ̃ ề ử ử ̣ chi u,  la   môt  da y  ca c  phâ n  t ,  mô i  phâ n  t ́   co

ự ̉ kiêu ký t

• H ng ký t

ằ ụ ặ ặ ơ ự ượ  đ c đ t trong c p nháy đ n. Ví d : ‘a’,

ự ắ ữ ặ ấ ả tr ng – gi a c p d u nháy ‘ ph i có 1 ‘1’, ‘ ’ (Ký t

ả ắ ) kho ng tr ng

• H ng chu i đ

90

90

ỗ ượ ằ ụ ặ ặ c đ t trong c p nháy kép. Ví d : “ho

ỗ ỗ không  có  kho ng ả va  ten”,  “123”,  “”  (Chu i  r ng  –

tr ngắ )

Khái niệm

́ ́ ́ ́ ̀ ự ̃ • Chuô i  ky   t ự ượ   đ c  kê t  thu c  bă ng  ky   t ‘\0’  (giá

̃ ̀ ị ̣ ̉ ́ tr   0).  Do  đó  khi  khai  ba o  đô  da i  cua  chuô i  luôn

̀ ́ ư ử ̉ ư ự ́ luôn khai ba o d  1 phâ n t ́  đê ch a ky  t ‘\0’.

• Ví d : Chu i

ụ ỗ “NGUYEN VAN A” đ ượ ư c l u

‘N’ 0

‘G’ 1

‘U’ 2

‘Y’ 3

‘E’ 4

‘N’ 5

‘ ‘ 6

‘V’ 7

‘A’ 8

‘N’ 9

‘ ‘ 10

‘A’ 11

‘\0’ 12

91

91

ự  Chu i g m 13 ký t ỗ ồ

Khai báo chuỗi

̃ ́ ́ự char  < Tên chuô i > [< Sô  ký t tô i đa>] ;

Vi  dú ̣: char str[25];

̃ ̀ ự ̉ ̉ Ý nghi a khai ba o co  ́ ́ 1 mang kiêu ký t tên la  str

̀ ́ ́ ử ̉ ư ố ư ự ̣ 25 phâ n t (nh  vây co  thê l u t i đa 24 ky  t ̀  vi

ử ứ ́ ư ự ế ỗ ̀ phâ n t th  24 đã ch a ký t k t thúc chu i ‘\0’

92

)

Khai báo chuỗi

́ • Ca ch 2 : Con trỏ

̃ char  *< Tên chuô i >;

̣ ́ Vi  du: char *str;

• Ph i c p phát b  nh  tr

ả ấ ớ ướ ộ c khi s  d ng chu i ỗ str

Thư viện ử ụ malloc.h

• Ví d : ụ

char *str;

str = (char*)malloc(30); //C p phát b  nh  cho str g m 30  93 ký tự

ự ế

ầ ấ

!!!Gán tr c ti p thì không c n c p phát b  nh

Nhập chuỗi – string.h

• Cu  pha p:

́ ́

char *gets(char *str);

́ ́ ̣ ́  phi m cho đê n khi nhâ n

̣ ừ  nhâp t ̀ ́ ̀ Nhân ca c ky  t phi m ́ ự ́ Enter va  đ a va o chu i  ỗ str ư

94

Ví d :ụ

int main() { char str[80]; printf("Nhap vao chuoi: "); gets(str); printf("Chuoi vua nhap la: %s\n", str); getch(); return 0; }

Nhập chuỗi

ư ể ể ỗ ậ scanf đ  nh p chu i có

• L u ý: Không th  dùng hàm  kho ng tr ng

s  nh p vào chu i:

• Ví d :ụ

ỗ “Nguyen Van An” “Nguyen”

ả ử ậ Gi ả ấ ế Thì k t qu  xu t ra màn hình là:  ỗ “Nguyen”) ỉ ư (do str ch  l u chu i

ả ắ

int main() { char str[80]; printf("Nhap vao chuoi: "); scanf("%s", &str); printf("Chuoi vua nhap la: %s\n", str); getch(); return 0; }

95

Xuất chuỗi – string.h

• Cú pháp : int puts (const char *s);

• Ví dụ:

int main()

{

char *str = "Vi du xuat chuoi";

puts(str);

return 0;

}

 Có thể dùng printf(): printf(“%s”, str);

96

Các hàm xử lý chuỗi -

1.

Tính độ dài chuỗi: strlen

2.

Sao chép chuỗi: strcpy, strncpy

3.

Nối chuỗi: strcat, strncat

4.

So sánh chuỗi: strcmp, strncmp, stricmp, strnicmp

5.

Tìm kiếm: strchr, strstr

6.

Tách chuỗi: strtok

7.

Đổi thành chữ in HOA: strupr

8.

Đổi thành chữ in thường: strlwr

97

ỗ Tính đ  dài c a chu i

• Ví d :ụ

int strlen(char *s);

char *str = "Borland International";

98

̉ Do dai str = 21 printf("Do dai str = %d\n", strlen(str)); ́  Kê t qua:

Bài tập ví dụ - tính độ dài chuỗi

1.

Viết hàm đếm số ký tự trắng trong chuỗi

2.

Viết hàm in ra màn hình chuỗi theo thứ tự đảo ngược

3.

Viết hàm tìm xem ký tự ch có trong chuỗi không? Nếu có cho

biết vị trí xuất hiện đầu tiên của ch

4.

Viết hàm kiểm tra xem chuỗi có đối xứng hay không?

5.

Viết hàm đổi tất cả các ký tự có trong chuỗi thành chữ HOA (không dùng hàm strupr)

99

1. Đếm số ký tự trắng trong chuỗi

int DemKyTuTrang(char *s) { int d=0; int n=strlen(s); for(int i=0; i

100

2. In ra màn hình chuỗi theo thứ tự ngược

void XuatChuoiNguoc(char *s) { int n = strlen(s); for (int i = n - 1; i >= 0; i--) printf("%c", s[i]); }

101

Bài tập làm thêm – tính độ dài chuỗi

1.

Viết hàm tra xem trong chuỗi có ký tự số hay không nếu có

tách ra thành một mảng số riêng

2.

Viết hàm đổi ký tự hoa thành thường và ngược lại trong

chuỗi ký tự cho trước

3.

Viết chương trình tìm kiếm xem ký tự nào xuất hiện nhiều

nhất trong chuỗi

4.

Viết chương trình đảo ngược các ký tự trong chuỗi

Ví dụ:

Nhập: ABCDE

Chuỗi sau khi đảo ngược là: EDCBA

102

Sao chép chuỗi

́

̃

̀

• Sao che p nôi dung chuô i

scr va o chuô i

̃ dest

strcpy(char *dest, const char *scr);

• Ví d :ụ

̣

char dest[10]; char *src = "abcdefghi"; strcpy(dest, src); printf("Chuoi dest: %s", dest);

103

103

́

̉  Chuoi dest: abcdefghi

 Kê t qua:

Sao chép chuỗi

ự ừ  t

chuô i ̃

• Che p ́ n ký t

scr sang dest

strncpy(char *dest, const char *scr, int n);

• Ví d :ụ

char dest[4]; char *src = "abcdefghi"; strncpy(dest, src, 3); printf("%s\n", dest);

104

̉ abc

́  Kê t qua:

104

Nối chuỗi

• Nối chuỗi s2 vào sau chuỗi s1

strcat(char *s1, char *s2);

• Ví dụ:

char s1[] = "Khoa"; char s2[] = "CNTT"; strcat(s1, " ");  Kết quả: Khoa CNTT strcat(s1, s2); printf("%s", s1);

105

Nối chuỗi

• Nối n ký tự đầu tiên của chuỗi s2 vào sau chuỗi s1

strncat(char *s1, char *s2, int n);

• Ví dụ:

char s1[] = "Khoa"; char s2[] = "CNTT"; strcat(s1, " ");  Kết quả: Khoa CN strncat(s1, s2, 2); printf("%s", s1);

106

So sánh chuỗi

• So sánh 2 chuỗi s1 và s2 theo nguyên tắc thứ tự từ điển. Phân

biệt chữ hoa và thường

int strcmp(char *s1, char *s2);

• Trả về:

• 0: nếu s1 bằng s2

• >0: nếu s1 lớn hơn s2

• <0: nếu s1 nhỏ hơn s2

107

So sánh chuỗi

ự ng HOA < Ký t

108

 Kết quả: Chuoi s1 lon hon chuoi s2

ự ườ  th !!! Ký t VD: ‘A’ < ‘a’ (do mã Ascii ‘A’ = 65, mã Ascii ‘a’ =  97) char s1[] = "abc"; char s2[] = "Abc"; int kq = strcmp(s1, s2); if (kq == 0) printf("Hai chuoi bang nhau"); else if (kq < 0) { printf("Chuoi s1 nho hon chuoi s2"); } else printf("Chuoi s1 lon hon chuoi s2");

So sánh chuỗi

• So sánh n ký tự đầu tiên của s1 và s2, giá trị trả về tương tự

hàm strcmp()

int strncmp(char *s1,char *s2, int n);

• Ví dụ:

char s1[] = "abcd"; char s2[] = "abef"; if(strncmp(s1, s2, 2)==0) printf("Giong nhau"); else printf("Khac nhau");

 Kết quả: Giong nhau

109

So sánh chuỗi

• So sánh chuỗi s1 và s2 nhưng không phân biệt hoa thường,

giá trị trả về tương tự hàm strcmp()

int stricmp(char *s1, char *s2);

• Ví dụ:

char s1[] = "abcd"; char s2[] = "abCD"; if(stricmp(s1, s2)==0) printf("Giong nhau"); else printf("Khac nhau");  Kết quả: Giong nhau

110

So sánh chuỗi

• So sánh n ký tự đầu tiên của s1 và s2, không phân biệt hoa

thường, giá trị trả về tương tự hàm strcmp()

int strnicmp(char *s1, char *s2, int n);

• Ví dụ:

char s1[] = "aBcd"; char s2[] = "Abef"; if(strnicmp(s1, s2, 2)==0) printf("Giong nhau"); else printf("Khac nhau");  Kết quả: Giong nhau

111

Tìm ký tự trong chuỗi

• Tìm sự xuất hiện đầu tiên của ký tư c trong chuỗi s.

char *strchr(char *s, char c);

• Trả về:

NULL: nếu không có

Con trỏ đến ký tự c xuất hiện trong s: nếu tìm thấy

112

Tìm ký tự trong chuỗi

• Ví dụ:

 Kết quả: m xuat hien tai vi tri 8

char s[15]; char *ptr, c = 'm'; strcpy(s, "Vi du tim ky tu"); ptr = strchr(s, c); if (ptr) printf("%c xuat hien tai vi tri %d", c, ptr-s); else printf("Khong tim thay");

113

Tìm chuỗi con

• Tìm sự xuất hiện đầu tiên của chuỗi s2 trong chuỗi s1.

char *strstr(char *s1, char *s2);

• Trả về:

NULL: nếu không có

Ngược lại: Con trỏ vào chuỗi s2 xuất hiện trong s1

114

Tìm chuỗi con

• Ví dụ:

 Kết quả: Vi tri xuat hien cua s2: 13

char *s1 = "Borland International"; char *s2 = "nation", *ptr; ptr = strstr(s1, s2); if(ptr!=NULL) printf("Vi tri xuat hien cua s2: %d", ptr-s1); else printf("Khong ton tai chuoi s2");

115

Tách chuỗi

char *strtok(char *s1, char *s2);

• Nếu s2 có xuất hiện trong s1: Tách chuỗi s1 thành 2 chuỗi: Chuỗi đầu là những ký tự cho đến khi gặp s2 đầu tiên, chuỗi sau là những ký tự còn lại của s1 sau khi đã bỏ đi s2 xuất hiện trong s1

• Nếu s2 không xuất hiện trong s1 thì kết quả vẫn là s1

116

Tách chuỗi

• Ví dụ:

 Kết quả: S11 = abc S12 = d

char input[16] = "abc,d"; char *p; // Lay chuoi dau p = strtok(input, ","); if (p) printf("S11 = %s\n", p); // Lay chuoi con lai, tham so dau la NULL p = strtok(NULL, ""); if (p) printf("S12 = %s", p);

117

Bài tập tách chuỗi

1.

Viết hàm đếm xem một chuỗi cho trước có bao nhiêu từ (các từ cách nhau bằng khoảng trắng)

2.

Viết hàm đảo ngược các từ

3.

Viết hàm tách các từ phân biệt và in ra màn hình (các từ các nhau bởi dấu chấm câu hoặc khoảng trắng)

4. Viết hàm kiểm tra xem chuỗi có tuần hoàn hay không?

5. Viết hàm đổi những ký tự đầu tiên của mỗi từ thành

chữ in HOA

118

Đổi sang chữ in HOA

• Đổi chuỗi str thành chuỗi in HOA

char* strupr(char *str);

• Ví dụ:

char s1[] = "aBcd";  Kết quả: s2 = ABCD char *s2 = strupr(s1); printf("s2 = %s", s2);

119

Đổi sang chữ in thường

• Đổi chuỗi str thành chuỗi in thường

char* strlwr(char *str);

• Ví dụ:

char s1[] = "aBcd";  Kết quả: s2 = abcd char *s2 = strlwr(s1); printf("s2 = %s", s2);

120

Q&A

121