Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
1
Chương 2
KIỂU DỮ LIỆU CÓ CẤU TRÚC
KỸ THUẬT LẬP TRÌNH NÂNG CAO
TRƯỜNG CAO ĐẲNG CNTT TP.HCM
KHOA CÔNG NGHỆ THÔNG TIN
Giảng Viên: ThS. Dương Thành Phết
Email: [email protected]
Website: http://www.thayphet.net
Tel: 0918158670 – facebook.com/DuongThanhPhet
2
1. Kiểu dữ liệu mảng 1 chiều
2. Các thao tác trên mảng 1 chiều
3. Mảng 2 chiều
4. Kiểu chuổi ký tự
5. Kiểu cấu trúc – Mảng cấu trúc
6. Kiểu tập tin - File
2
NỘI DUNG
3
1.1 Khái niệm
Mảng thực chất la môt biên bao gôm nhiều biên thanh
phân đươc cấp phát bô nhớ liên tuc.
Các thanh phân cua mảng la tập hơp các biên co cung
kiểu dữ liệu va cung tên. Do đo để truy xuất các biên
thanh phân, ta dung cơ chê chi muc (Vị trí).
3 0 1 2 3 4 5 6 7 8 9
Giá trị
Vị trí
1. KIỂU DỮ LIỆU MẢNG 1 CHIỀU
4
1.2. Khai báo
int a[100]; //Khai bao mang so nguyen a gom 100 phan tu
float b[50]; //Khai bao mang so thuc b gom 50 phan tu
char str[30]; //Khai bao mang ky tu str gom 30 ky tu
4
< Kiêu dư liêu > < Tên mang > [ < Sô p.tư tôi đa cua mang> ] ;
1. KIỂU DỮ LIỆU MẢNG 1 CHIỀU
5
1.3. Gán giá trị ban đầu cho mảng
int a[5] = {3, 6, 8, 1, 12};
a[0] = 3, a[1] = 6, a[2] = 8, …
5
int a[10] = {0};
a[0]=a[1]=a[2]=a[3]=…=a[9]=0
1. KIỂU DỮ LIỆU MẢNG 1 CHIỀU
6
1.4. Truy xuất
Vị trí 0 1 2 3 4
A[0] A[1] A[2] A[3] A[4]
6
1. KIỂU DỮ LIỆU MẢNG 1 CHIỀU
7
1. Nhập/Xuất mảng
void NhapMang (int a[], int n){
for (int i = 0; i < n; i ++){
cout<<“Nhap phan tu thu “<<i<<“: “;
cin>>a[i];
}
}
7
void XuatMang (int a[], int n){
for (int i = 0; i < n; i ++)
cout<<a[i]<<“\t”;
}
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
8
void main ( ){
int a[MAX] , n;
cout<<“Nhap kich thuoc mang: “;
cin>>n;
NhapMang (a,n);
cout<<“Cac gia tri cua mang vua nhap: ”<<endl;
XuatMang (a,n);
}
8
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
9
Xuất các phần tử thỏa điều kiện
Mẫu 1:
void LietKeXXX(int a[], int n){
for (int i = 0; i<n; i++)
if (a[i] thỏa điều kiện)
Xuất a[i];
}
9
Mẫu 2:
void LietKeXXX(int 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];
}
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
10
Ví dụ 1: Liệt kê các phân tử co giá trị chẵn trong mảng
10
void LietKeChan(int a[], int n){
for (int i = 0; i<n; i++)
if (a[i] %2 ==0)
cout<<a[i]<<“\t”;
}
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
11
Ví dụ 2: Liệt kê các phân tử co giá trị lớn hơn x trong mảng
11
void LietKeLonHonX(int a[], int n, int x){
for (int i = 0; i<n; i++)
if (a[i] > x)
cout<<a[i]<<“\t”;
}
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
12
2.2. Đếm
12
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
Mẫu 1:
int DemXXX(int a[], int n){
int d = 0;
for (int i = 0; i<n; i++)
if (a[i] thỏa điều kiện)
d++;
return d;
}
Mẫu 2:
int DemXXX(int 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;
}
13
bool LaSNT(int k) {
int d = 0;
for (int i = 1; i <= k; i++)
if (k % i == 0)
d++;
return (d == 2);
}
int DemSNT(int a[], int n){
int d = 0;
for (int i = 0; i<n; i++)
if (LaSNT(a[i]) ==true)
d++;
return d;
}
Ví dụ 1: Đêm các phân tử co giá trị la số nguyên tố
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
14
Ví dụ 2: Đêm các phân tử co trong mảng ma giá trị nhỏ hơn x
int DemNhoHonX(int a[], int n, int x){
int d = 0;
for (int i = 0; i<n; i++)
if (a[i] < x)
d++;
return d;
}
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
15
2.3. Tìm kiếm
Mẫu 1: Tìm và trả về vị trí phần tử có giá trị lớn nhất
int TimVTMax(int a[], int n){
int vtmax = 0;
for (int i = 0; i < n; i++)
if (a[i] > a[vtmax])
vtmax = i;
return vtmax;
}
15
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
Mẫu 2: Tìm vị trí phần tử có giá trị x
(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;
return -1;
}
16
2.4. Kiểm tra mảng có thỏa đk cho trước
Trường hợp 1: Kiểm tra tồn tại môt phân tử trong mảng
thỏa điều kiện nao đo cho trước tìm phân tử thỏa điều
kiện để kêt luận.
16
Mẫu 1:
bool KiemTraTonTaiXXX(int a[], int n){
for (int i = 0; i<n; i++)
if (a[i] thỏa điều kiện)
return true;
return false;
}
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
17
17
Mẫu 2:
bool KiemTraXXX(int a[], int n){
for (int i = 0; i<n; i++)
if (a[i] không thỏa điều kiện)
return false;
return true;
}
Trường hợp 2: Kiểm tra tất cả các phân tử thỏa điều
kiện nao đ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.
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
18
bool KiemTraTonTaiLe(int a[], int n){
foreach (int giatri in a)
if (giatri % 2 != 0)
return true;
return false;
}
18
Ví dụ 1: Kiểm tra xem mảng co tôn tại số lẻ không?
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
19
Ví du 2: Kiểm tra xem mảng co toan giá trị âm không?
(true: có/ false: không)
19
bool KiemTraToanAm(int a[], int n){
for (int i = 0; i<n; i++)
if (a[i] >= 0)
return false;
return true;
}
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
20
2.5. Tính toán các phần tử trong mảng
Mẫu tính tổng:
int TongXXX(int a[], int n){
int s = 0;
for (int i = 0; i<n; i++)
if (a[i] thỏa điều kiện)
s += a[i];
return s;
}
20
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
21
Ví dụ: Tính tổng các phân tử co giá trị lẻ trong mảng
21
int TongLe(int a[], int n) {
int s = 0;
for (int i = 0; i<n; i++)
if (a[i] %2!=0)
s += a[i];
return s;
}
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
22
Mẫu tính trung bình:
float TrungBinhXXX(int a[], int n){
int s = 0;
int d = 0;
for (int i = 0; i<n; i++)
if (a[i] thỏa điều kiện){
s += giatri;
d ++;
}
if (d==0)
return 0;
return (float) s / d;
} 22
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
23
Ví dụ: Tính giá trị trung bình các phân tử co giá trị âm trong
mảng
23
float TrungBinhAm(int a[], int n){
long s = 0;
int d = 0;
for (int i = 0; i<n; i++)
if (a[i] < 0){
s += a[i];
d++;
}
if (d == 0)
return 0;
return (float)s / d;
}
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
24
Minh họa thuật toán
24
2 12 8 5 1 6 4
i=1 j=2 j=5 i=2 j=3 j=4 i=3 j=7 i=4 j=6 i=5 i=6 i=7
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
2.6. Sắp xếp
25
25
2. CÁC THAO TÁC TRÊN MẢNG 1 CHIỀU
Mẫu phương thức sắp thứ tự tăng:
void SapTang(int 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(int &a, int &b){
int tam = a;
a = b;
b = tam;
}
Mảng hai chiều thực chất la mảng môt chiều trong đo
môi phân tử cua mảng la môt mảng môt chiều, va
đươc truy xuất bơi hai chi số dong va côt.
Từ khái niệm trên ta co thể đưa ra môt khái niệm về
mảng nhiều chiều như sau: mảng co từ hai chiều
trơ lên goi la mảng nhiều chiều.
26
3. MẢNG 2 CHIỀU
3.1 Giới thiệu
3.2. Khai báo
Cách 1:
< Kiểu dư liệu > < Tên mảng > [< Sô dong][<Sô côt>];
Ví du:
int A[5][10]; // Khai báo mảng int gồm 5 dòng, 10 cột
float b[7][8]; // Khai báo mảng float gồm 7 dòng, 8 cột
Cách 2 :
< Kiểu dư liệu > **<Tên mảng>;
Ví du :
int **A ; // Khai báo mảng động 2 chiều kiểu int
float **B ; // Khai báo mảng động 2 chiều kiểu float
27
3. MẢNG 2 CHIỀU
3.3. Truy xuất
Để truy xuất các thanh phân cua mảng hai chiều ta
phải dựa vao chi số dong va chi số côt.
Ví du: int A[3][4] = { {2,3,9,4} , {5,6,7,6} , {2,9,4,7} };
Với các khai báo như trên ta co:
A[0][0] = 2; A[0][1] = 3;
A[1][1] = 6; A[1][3] = 6;
28
3. MẢNG 2 CHIỀU
3.4. Các thao tác
Nhập/ xuất
Tìm kiêm
Đêm
Tính tổng/ trung bình
Sắp xêp dong/ côt
Xoa dong/ côt
Chèn thêm dong/ côt
29
3. MẢNG 2 CHIỀU
3.4. Ma trận vuông
Số dong = Số côt
Đương cheo chính cua ma trận vuông:
chi sô dòng = chi sô cột
Đương cheo phụ của ma trận vuông:
chi sô cột + chi sô dòng = kích thước - 1
30
3. MẢNG 2 CHIỀU
Cheo chính
Cheo phu
4.1. Giới thiệu
Chuôi ky tư la môt day các phân tư, môi phân tư co kiểu
ky tư.
Khai báo cách 1:
char < Tên chuỗi > [ < Sô ky tư tôi đa cua chuỗi > ] ;
Ví du: char chuoi[25];
Khai báo 1 mảng kiểu ky tư tên la chuoi co 25 phân tư
(lưu đươc 24 ky tư, ký tự 25 la ký tự kêt thúc chuôi „\0‟ )
Khai báo cách 2:
char *< Tên chuôi >;
Ví du : char *chuoi;
Chuôi ký tự không giới hạn chiều dai 31
4. CHUỖI KÝ TỰ
4.2. Nhập
cin.getline(chuoi, số ký tự tối đa);
Ví du:
char *str;
str = new char [30];
cin.getline(str, 30);
32
4. CHUỖI KÝ TỰ
4.3. Các hàm thư viện – <string.h>
Tính đô dai cua chuôi s
int strlen(char s[]);
Sao chep nôi dung chuôi nguôn vao chuôi đích
strcpy(char đích[], char nguôn[]);
Chep n ky tư tư chuôi nguôn sang chuôi đích. Nêu chiều dai nguôn < n thi ham se điền khoảng trắng cho đu n ky tư vao đích
strncpy(char đích[], char nguôn[], int n);
33
4. CHUỖI KÝ TỰ
Nối chuôi s2 vai chuôi s1
strcat(char s1[],char s2[]);
Nối n ky tư đâu tiên cua chuôi s2 vao chuôi s1
strncat(char s1[],char s2[],int n);
So sánh 2 chuôi s1 va s2 theo nguyên tắc thư tư.
Phân biệt chư hoa va thương. Tra vê:
0: nêu s1 băng s2.
>0: nêu s1 lớn hơn s2.
<0: nêu s1 nho hơn s2.
int strcmp(char s1[],char s2[]);
34
4. CHUỖI KÝ TỰ
So sánh n ký tự đâu tiên cua s1 va s2, giá trị trả về
tương tự ham strcmp()
int strncmp(char s1[],char s2[], int n);
So sánh chuôi s1 va s2 nhưng không phân biệt hoa
thương, giá trị trả về tương tự ham strcmp()
int stricmp(char s1[],char s2[]);
So sánh n ký tự đâu tiên cua s1 va s2 nhưng không
phân biệt hoa thương, giá trị trả về tương tự ham
strcmp()
int strnicmp(char s1[],char s2[], int n);
35
4. CHUỖI KÝ TỰ
Tìm sự xuất hiện đâu tiên cua ky tư c trong chuôi s.
Tra vê:
NULL: nêu không co
Địa chi c: nêu tìm thấy
char *strchr(char s[], char c);
Tìm sư xuất hiện đâu tiên cua chuôi s2 trong chuôi
s1. Trả vê:
NULL: nêu không co
Ngươc lại: Địa chi bắt đâu chuôi s2 trong s1
char *strstr(char s1[], char s2[]);
36
4. CHUỖI KÝ TỰ
Tách chuỗi: Nêu s2 co xuất hiện trong s1: Tách chuôi s1
thanh hai chuôi: Chuôi đâu la những ky tư cho đên khi
găp chuôi s2 đâu tiên, chuôi sau la những ky tư con lại
cua s1 sau khi đa bỏ đi chuôi s2 xuất hiện trong s1.
37
4. CHUỖI KÝ TỰ
Nêu s2 không xuất hiện trong s1 thi kêt quả chuôi tách vân la s1.
char *strtok(char s1[], char s2[]);
5.1. Giới thiệu
Cấu trúc thực chất la môt kiểu dữ liệu do ngươi dung
định nghia băng cách sử dung các kiểu dữ liệu cơ sơ
thanh môt kiểu dữ liệu phưc hơp nhiều thanh phân
38
5. KIỂU CÓ CẤU TRÚC
5.2. Khai báo
39
5. KIỂU CÓ CẤU TRÚC
Cú pháp 1:
struct <Têncấutrúc>
{
<Kiểu> <Trương 1> ;
<Kiểu> <Trương 2> ;
……..
<Kiểu> <Trương n> ;
};
struct <Têncấutrúc> <Tênbiên>
struct SinhVien
{
char MSSV[6] ;
char HoTenSV[30];
bool Phai ;
float Toan, Ly, Hoa;
};
struct SinhVien SV;
5.2. Khai báo
40
5. KIỂU CÓ CẤU TRÚC
Cú pháp 2:
typedef struct
{
<Kiểu> <Trương 1> ;
<Kiểu> <Trương 2> ;
……..
<Kiểu> <Trương n> ;
} <Têncấutrúc>;
<Têncấutrúc> <Tênbiên>
typedef struct
{
char MSSV[6] ;
char HoTenSV[30];
bool Phai ;
float Toan, Ly, Hoa;
}Sinhvien;
SinhVien SV;
41
5. KIỂU CÓ CẤU TRÚC
5.3. Khởi tạo cấu trúc
Việc khơi tạo cấu trúc co thể đươc thực hiện trong
lúc khai báo biên cấu trúc.
Các trương cua cấu trúc đươc khơi tạo đươc đăt
giữa 2 dấu { va }, chúng đươc phân cách nhau bơi
dấu phẩy (,).
struct SinhVien SV={„sv01‟,‟nguyen thi lan‟,0,6.0,7.5,8.0};
42
5. KIỂU CÓ CẤU TRÚC
5.4. Truy xuất từng trường trong biến cấu trúc
Cú pháp:
<Biên cấu trúc>.<Tên trương> ;
s = SV.HoTenSV; //nguyen thi lan
43
5. KIỂU CÓ CẤU TRÚC
5.5. Mảng cấu trúc
Cách khai báo tương tự như mảng môt chiều hay
ma trận (Kiểu dữ liệu nhưng kiểu dữ liệu cua môi
phân tử la kiểu dữ liệu co cấu trúc).
Cách truy cập phân tử trong mảng cung như truy
cập trên mảng môt chiều hay ma trận. Nhưng do
từng phân tử co kiểu cấu trúc nên phải chi định ro
cân lấy thanh phân nao.
44
5. KIỂU CÓ CẤU TRÚC
struct PhanSo
{
int tu, mau;
};
struc PhanSo ps;
void main()
{
int n; //Kích thước của mảng
PhanSo a[100]; //Mảng các phân số
//Các lệnh
}
45
5. KIỂU CÓ CẤU TRÚC
Do kiểu dữ liệu co cấu trúc thương chưa rất
nhiều thanh phân nên khi viêt chương trình loại
nay ta cân lưu ý:
Xây dựng ham xử lý cho môt kiểu cấu trúc.
Muốn xử lý cho mảng cấu trúc, ta goi lại ham xử
lý cho môt kiểu cấu trúc đa đươc xây dựng băng
cách dung vong lăp.
46
5. KIỂU CÓ CẤU TRÚC
Bài tập 1. Định nghia kiểu:
struct Hoso{
char Hoten[40];
float Diem;
char Loai[10];
}
Viêt chương trình nhập thôn tin cua n hoc sinh (Ho
tên, điểm), xêp loại như sau:
Điểm 9,10 Giỏi Điểm 7,8 Khá
Điểm 5,6 Trung bình Điểm <5 Không đạt
In DS như sau:
XEP LOAI VAN HOA
Ho tên Diem Xep loai
Nguyen Thi Lan 8 Khá
Tran Van Diep 4 Khong dat
47
5. KIỂU CÓ CẤU TRÚC
Bài tập 2. Viêt chương trình khai báo kiểu dư liệu đê
biểu diên môt phân sô. Hay viêt ham thực hiện những
công việc sau:
Rút gon phân sô.
Tính tổng, hiệu, tích, thương hai phân sô (kêt quả
phải tối giản)
So sánh hai phân sô.
6.1. Giới Thiệu
Tập tin văn bản: tập tin dung để ghi các ký tự lên đia
theo các dong.
Tập tin nhị phân: tập tin dung để ghi các cấu trúc
dạng nhị phân (đươc ma hoá).
48
6. KIỂU TẬP TIN - FILE
6.2. Thao tác với tập tin
Bước 1: Mơ tập tin để đoc/ ghi.
Bước 2: Các xư lý trên tập tin.
Bước 3: Đong tập tin.
49
6. KIỂU TẬP TIN - FILE
6.3. Lớp fstream - <fstream.h>
Mơ file
fstream::open()
Đoc file
fstream::Operator >>
Ghi dữ liệu vao file
fstream::Operator <<
Đong file
fstream::close()
50
6. KIỂU TẬP TIN - FILE
Tạo tập tin văn bản
void main()
{
fstream file(“d:\\file_text.txt”, ios::out);
file<<“Write to file";
file.close();
}
51
6. KIỂU TẬP TIN - FILE
Đọc toàn bộ tập tin văn bản
void main()
{
char str[2000];
fstream file(“d:\\file_text.txt”, ios::in);
while(file >> str)
cout << str ;
file.close();
}
52
6. KIỂU TẬP TIN - FILE
Đọc từng dòng tập tin văn bản
void main()
{
char str[2000];
fstream file(“d:\\file_text”, ios::in);
while(!file.eof())
{
file.getline(str,2000);
cout <<str;
}
file.close();
}
53
6. KIỂU TẬP TIN - FILE
54
The End.