Bài giảng Kỹ thuật lập trình - Chương 1: Mảng một chiều cung cấp cho người học các kiến thức: Khái niệm kiểu dữ liệu mảng một chiều, khai báo, các thao tác nhập/ xuất mảng, kỹ thuật tìm kiếm, liệt kê giá trị trong mảng, kỹ thuật xóa, chèn, chuỗi ký tự và các thao tác xử lý cơ bản.
Trang 3KHÁI NIỆM VÀ KHAI BÁO
Trang 5Khai báo
<KDL> < Tên mảng > [< Số phần tử tối đa của mảng>] ;
Nhằm thuận tiện cho việc viết chương trình, ta nên định nghĩa hằng số MAX
ở đầu chương trình – là kích thước tối đa của mảng - như sau:
Trang 6Khai báo, gán giá trị ban đầu
Trang 7Truy xuất giá trị
TênMảng [vị trí cần truy xuất]
Trang 9THAO TÁC NHẬP VÀ XUẤT
Trang 10 Nhập a[i], với 0 ≤ i ≤ n-1
Trang 12void XuatMang ( int a [], int n )
Trang 13Phát sinh ngẫu nhiên giá trị nguyên
• Sử dụng thư viện hàm <time.h> và <stdlib.h>
• 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
Trang 14Ví dụ: Chương trình tạo mảng số nguyên có giá trị ngẫu nhiên từ 1 đến MAX
void NhapKichThuoc ( int & n );
void PhatSinh ( int a [], int n );
void XuatMang ( int a [], int n );
Trang 15void NhapKichThuoc ( int & n )
Trang 18XUẤT CÓ ĐIỀU KIỆN
Trang 19Liệt kê các phần tử thỏa đk cho trước
Mẫu 1:
void LietKeXXX(<KDL> a[], int n)
{
for (int i = 0; i<n; i++)
if ( a[i] thỏa điều kiện )
Xuất a[i];
}
Trang 20Liệt kê các phần tử thỏa đk cho trước
Mẫu 2:
void LietKeXXX(<KDL> a[], int n, int x)
{
for (int i = 0; i<n; i++)
if ( a[i] thỏa điều kiện so với x )
Xuất a[i];
}
Trang 21Ví 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)
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<n; i++)
if ( a[i] > x )
printf(“%d\t”, a[i]);
Trang 22Ví 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)
printf(“Nhap phan tu tai vi tri %d: “, i);
scanf(“%d”, &a[i]);
}
Trang 23void XuatMang (int a[], int n)
Trang 25Bài tập tại lớp
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:
1 Nhập vào kích thước mảng (0<n<=100), nếu nhập
không thỏa miền giá trị thì cho phép người dùng nhập lại
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 đến 4
Trang 26THAO TÁC ĐẾM SỐ LƯỢNG
Trang 27for (int i = 0; i<n; i++)
if (a[i] thỏa điều kiện)
d++;
return d;
Trang 28Mẫu 2:
int DemXXX(<KDL> a[], int n, int x)
{
int d = 0;
for (int i = 0; i<n; i++)
if (a[i] thỏa điều kiện so với x)
d++;
return d;
}
Trang 29Ví 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<n; i++) {
if (LaSNT(a[i]) ==1) {
d++;
} }
Trang 30int DemNhoHonX(int a[], int n, int x)
Trang 31Ví 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 Đếm số lượng các phần tử là số nguyên tố có trong mảng
#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]);
Trang 32int DemSNT(int a[], int n) {
int d = 0;
for (int i = 0; i<n; i++)
if (LaSNT(a[i]) ==1) d++;
Trang 35THAO TÁC TÌM KIẾM
Trang 36Tì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
Đã tìm thấy tại
vị trí 5
Đã hết mảng
Trang 37(nếu x không xuất hiện trong mảng trả về -1)
int TimVTX(int a[], int n, int x)
Trang 40vtmin
Trang 415 nhỏ hơn 10 nên cập nhật vị trí min
10
10
Trang 427 lớn hơn 5 nên không cập nhật vị trí
Trang 449 lớn hơn 3 nên không cập nhật vị trí
Trang 4615 lớn hơn 1 nên không cập nhật vị trí
Trang 479
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
Trang 48Code minh họa tìm vị trí phần tử có giá trị nhỏ nhất
Trang 50THAO TÁC TÍNH TOÁN
Trang 51Tính tổng, giá trị trung bình có điều kiện
Trang 53Ví dụ 1: Tính tổng các phần tử có giá trị lẻ trong mảng trong mảng
Trang 54Ví dụ 2: Tính giá trị trung bình các phần tử có giá trị âm trong mảng số
Trang 55SẮP XẾP MẢNG THEO THỨ TỰ
Trang 56Mẫu phương thức sắp thứ tự tăng:
void SapTang(<KDL> a[], int n)
Trang 57THAO TÁC KIỂM TRA GIÁ TRỊ MẢNG
CÓ THỎA ĐIỀU KIỆN
Trang 58Kiể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
Trang 59Kiểm tra tồn tại
int KiemTraTonTaiXXX(<KDL> a[], int n)
{
for (int i = 0; i<n; 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
}
Trang 60Kiể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)
Trang 61Kiể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
Trang 62Kiểm tra với mọi phần tử
int KiemTraXXX(<KDL> a[], int n)
{
for (int i = 0; i<n; i++)
if (a[i] không thỏa điều kiện)
return 0;
return 1;
}
Trang 63Kiể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
Trang 64Bà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?
Trang 651 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);
Trang 66int LaSNT(int k)
Trang 682 Kiểm tra mảng có thứ tự tăng dần?
int LaTangDan(int a[], int n)
Trang 693 Kiểm tra chẵn lẻ xen kẽ?
int LaChanLeXenKe(int a[], int n)
Trang 704 Kiểm tra âm dương xen kẽ
int LaAmDuongXenKe(int a[], int n)
Trang 71THAO TÁC CHÈN
Trang 729 111
Trang 75Chèn phần tử vào mảng
BT: Hãy viết hàm chèn phần tử có giá trị x vào vị trí k cho trước trong mảng số nguyên a kích thước n theo mẫu sau:
void ChenX(int a[], int &n, int x, int k);
Trang 77Bà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)
Trang 80THAO TÁC XÓA
Trang 86Bà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)
Trang 89CHUỖI KÝ TỰ
Trang 90Khái niệm
• Chuỗi ký tự là trường hợp đặc biệt của mảng 1 chiều,
là một dãy các phần tử, mỗi phần tử có kiểu ký tự
• Hằng ký tự được đặt trong cặp nháy đơn Ví dụ: ‘a’,
‘1’, ‘ ’ (Ký tự trắng – giữa cặp dấu nháy ‘ phải có 1 khoảng trắng )
• Hằng chuỗi được đặt trong cặp nháy kép Ví dụ: “ho va
ten”, “123”, “” (Chuỗi rỗng – không có khoảng trắng )
Trang 91Khái niệm
• Chuỗi ký tự được kết thúc bằng ký tự ‘\0’ (giá trị 0)
Do đó khi khai báo độ dài của chuỗi luôn luôn khai báo dư 1 phần tử để chứa ký tự ‘\0’.
• Ví dụ: Chuỗi “NGUYEN VAN A” được lưu
Chuỗi gồm 13 ký tự
‘N’ ‘G’ ‘U’ ‘Y’ ‘E’ ‘N’ ‘ ‘ ‘V’ ‘A’ ‘N’ ‘ ‘ ‘A’ ‘\0’
Trang 92Khai báo chuỗi
char < Tên chuỗi > [< Số ký tự tối đa>] ;
Ví dụ: char str[25];
Ý nghĩa khai báo 1 mảng kiểu ký tự tên là str có 25 phần tử (như vậy có thể lưu tối đa 24 ký tự vì phần tử
thứ 24 đã chứa ký tự kết thúc chuỗi ‘\0’ )
Trang 93Khai báo chuỗi
str = (char*)malloc(30); //Cấp phát bộ nhớ cho str gồm 30
Thư viện malloc.h
Trang 95Nhập chuỗi
• Lưu ý: Không thể dùng hàm scanf để nhập chuỗi có
khoảng trắng
• Ví dụ: Giả sử nhập vào chuỗi: “Nguyen Van An”
Thì kết quả xuất ra màn hình là: “Nguyen”
(do str chỉ lưu chuỗi “Nguyen”)
Trang 96Xuất chuỗi – string.h
• Cú pháp : int puts (const char *s);
Trang 97Các hàm xử lý chuỗi - <string.h>
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
Trang 98Tính độ dài của chuỗi
int strlen(char *s);
• Ví dụ:
char *str = "Borland International";
printf("Do dai str = %d\n", strlen(str));
Kết quả: Do dai str = 21
Trang 99Bà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)
Trang 1012 In ra màn hình chuỗi theo thứ tự ngược
void XuatChuoiNguoc(char *s)
Trang 102Bà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
Trang 103Sao chép chuỗi
• Sao chép nội dung chuỗi scr vào chuỗi dest
strcpy(char *dest, const char *scr);
Trang 104Sao chép chuỗi
• Chép n ký tự từ chuỗi scr sang dest
strncpy(char *dest, const char *scr, int n);
Trang 106Nố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);
Trang 107So 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
Trang 108printf("Chuoi s1 lon hon chuoi s2");
Kết quả: Chuoi s1 lon hon chuoi s2
Trang 112Tì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
Trang 114Tì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
Trang 115Tìm chuỗi con
• Ví dụ:
Kết quả: Vi tri xuat hien cua s2: 13
char *s1 = "Borland International";
Trang 116Tá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
Trang 118Bà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
Trang 119Đổi sang chữ in HOA
• Đổi chuỗi str thành chuỗi in HOA
char* strupr(char *str);
• Ví dụ:
Kết quả: s2 = ABCD char char s1[] = *s2 = strupr(s1);"aBcd";
printf("s2 = %s ", s2);
Trang 120Đổi sang chữ in thường
• Đổi chuỗi str thành chuỗi in thường
char* strlwr(char *str);
• Ví dụ:
Kết quả: s2 = abcd char char s1[] = *s2 = strlwr(s1);"aBcd";
printf("s2 = %s ", s2);
Trang 121Q&A