Tải bản đầy đủ (.pdf) (29 trang)

Bài giảng Giới thiệu lập trình: Cấu trúc mảng - TS. Lê Nguyên Khôi

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (217.13 KB, 29 trang )

Giới Thiệu Lập Trình
Cấu Trúc Mảng
TS. Lê Ngun Khơi
Trường Đại học Công nghệ, ĐHQGHN


Nội Dung
Khái niệm chung
Truyền mảng vào hàm
Lập trình với mảng

Giới Thiệu Lập Trình

1


Đặt Vấn Đề
Kiến thức về kiểu và biến không đủ để biểu
diễn, xử lý những kiểu dữ liệu phức tạp, ví dụ:
Danh sách điểm thi của một sinh viên
Danh sách sinh viên của lớp học
Cần lưu trữ và xử lý một chuỗi dữ liệu cùng kiểu
Sắp xếp, tìm kiếm, tính tốn trên chuỗi dữ liệu

Ngơn ngữ lập trình (C++) cung cấp các kiểu dữ
liệu có cấu trúc để xử lý các vấn đề trên
Trong đó mảng là cấu trúc dữ liệu thông dụng nhất
Mảng dùng để lưu trữ dữ liệu cùng kiểu
Giới Thiệu Lập Trình

2




Khái Niệm Chung
Mảng một chiều là chuỗi dữ liệu có cùng kiểu
Đặt tại các ô nhớ liên tiếp trong bộ nhớ
Mỗi phần tử mảng có một chỉ số riêng biệt
Sử dụng chỉ số để định vị & truy cập phần tử
Ví dụ: điểm thi 5 mơn của sinh viên lưu trữ
trong mảng có 5 phần tử (mảng diemSo)
Chỉ số

0

1

2

3

4

Dữ liệu

45

60

77

72


83

Mảng trên có 5 phần tử, lưu dữ liệu kiểu int,
chỉ số bắt đầu từ 0 đến 4
Giới Thiệu Lập Trình

3


Khái Niệm Chung
Chỉ số

0

1

2

3

4

Dữ liệu

45

60

77


72

83

Các phần tử của mảng có thể coi là biến số tên
diemSo[0], diemSo[1], diemSo[2], diemSo[3],
diemSo[4], có kiểu dữ liệu int
Chỉ số phần tử đặt trong ngoặc vuông ([])
Truy cập phần tử mảng, sử dụng:
Tên mảng (diemSo)
Và chỉ số phần tử là một giá trị nguyên hay biểu thức
giá trị nguyên
Giới Thiệu Lập Trình

4


Truy Cập Mảng
Chỉ số

0

1

2

3

4


Dữ liệu

45

60

77

72

83

Sử dụng tên mảng và chỉ số phần tử
diemSo[2] = 74;

// 77 -> 74

// với i=1, câu lệnh sau -> diemSo[3] = 75
diemSo[i+2] = 75; // 72 -> 75
// thực hiện tính tốn
tb = (diemSo[2] + diemSo[3]) / 2;
//in ra 45 và 83
cout << diemSo[0] << " " << diemSo[4];
Giới Thiệu Lập Trình

5


Khai Báo

Mảng phải được khai báo trước khi sử dụng
Khi khai báo phải quy định số phần tử mảng
Cú pháp:
KiểuDL TênMảng [SốPhầnTử];
Ví dụ:
int diemSo[5];
Khai báo một mảng có tên diemSo, có 5 phần tử,
lưu trữ giá trị kiểu int

Lưu ý:
Số phần tử của mảng không được thay đổi
Giới Thiệu Lập Trình

6


Nhập Dữ Liệu
Mảng sau khi khai báo, có thể được nhập dữ
liệu, và thực tiện tính tốn trên dữ liệu mảng
const int SO_MON_HOC = 5;
int main()
{
int diemSo[SO_MON_HOC];
double tongDiem = 0.0;
for (int i = 0; i < SO_MON_HOC; i++) {
cin >> diemSo[i];
tongDiem += diemSo[i];
}
cout << "diem trung binh: "
<< tongDiem / SO_MON_HOC;

}
Giới Thiệu Lập Trình

7


Khởi Tạo
Mảng có thể được khởi tạo như sau:
int diemSo[5] = {45, 60, 77, 72, 83};
Lưu ý: số giá trị trong danh sách khởi tạo (trong {})
không được vượt quá kích thước mảng (trong [])

Mảng cũng có thể được khởi tạo như sau:
int diemSo[] = {45, 60, 77, 72, 83};
C++ sẽ tự xác định độ dài của mảng dựa trên độ dài
của danh sách khởi tạo

Mảng không được khởi tạo, phần tử mảng có
giá trị khơng xác định (giống biến)
Giới Thiệu Lập Trình

8


Ứng Dụng
Thống kê số lần ra mặt giá trị từ 1 đến 6, sau
6000 lần tung xúc xắc
int main(){
const int SO_MAT = 6;
int dem[SO_MAT + 1] = { 0 };

for (int t = 0; t < 6000; t++) {
int mat = 1 + rand() % SO_MAT;
dem[mat]++;
}
for (int m = 1; m <= SO_MAT; m++) {
cout << m << "\t" << dem[m] << "\n";
}
return 0;
}
Giới Thiệu Lập Trình

9


Quản Lý Chỉ Số Phần Tử
Khai báo mảng có kích thước SốPhầnTử, chỉ
số các phần tử từ 0 đến SốPhầnTử - 1
Tất cả các chỉ số khác không hợp lệ
Truy cập vào các chỉ số khơng hợp lệ, ví dụ
diemSo[-1], diemSo[SO_MON_HOC]:
Truy cập ra vùng bộ nhớ ngồi mảng
Khơng gây lỗi cú pháp (lỗi dịch)
Có thể gây lỗi khi chạy chương trình
Chương trình chạy sai
Dừng đột ngột

Lập trình viên có trách nhiệm kiểm sốt giá trị chỉ số
Giới Thiệu Lập Trình

10



Truyền Mảng Cho Hàm
Dùng tên mảng làm tham số truyền cho hàm
void nhapMang(int diemSo[]) {
for (int i = 0; i < SO_MON_HOC; i++)
cin >> diemSo[i];
}
int main() {
int diemSo[SO_MON_HOC];
nhapMang(diemSo);
return 0;
}

Mảng được truyền theo kiểu tham chiếu, nhưng khơng
sử dụng tốn tử &
Hàm thay đổi giá trị trong mảng, kết thúc hàm, mảng
thay đổi
Giới Thiệu Lập Trình

11


Truyền Mảng Cho Hàm
Nếu không muốn hàm thay đổi giá trị trong mảng, sử
dụng khai báo hằng số trong chữ ký hàm đối với mảng
Thay đổi giá trị phần tử mảng (gán, nhập) gây lỗi dịch
double dtb(const int diemSo[], int soPT) {
double tong = 0.0;
for (int i = 0; i < soPT; i++)

tong += diemSo[i];
return (tong / soPT);
}
int main() {
int diemSo[SO_MON_HOC];
nhapMang(diemSo);
cout << "dtb: << dtb(diemSo, SO_MON_HOC);
return 0;
}
Giới Thiệu Lập Trình

12


Xâu Ký Tự
Kiểu dữ liệu xâu ký (thư viện string của C++)
Xâu ký tự là một chuỗi các ký tự, kết thúc '\0'
int main()
{
char ten1[20] = {'L','e',' ','B','e','\0'};
char ten2[20] = "Le Be";
cout << ten2;
cin >> ten1;
cin.getline(ten2, 15, '\n');
return 0;
}

Giới Thiệu Lập Trình

13



Lập Trình Với Mảng
Nhập & in dữ liệu
Tìm kiếm dữ liệu
Sắp xếp dữ liệu
Thêm & loại dữ liệu

Giới Thiệu Lập Trình

14


Nhập & In
void nhapMang(int a[], int soPhanTu){
for (int i = 0; i < soPhanTu; i++)
cin >> a[i];
}
void inMang(const int a[], int soPhanTu){
for (int i = 0; i < soPhanTu; i++)
cout << a[i] << endl;
}
int main() {
const int SO_MON_HOC = 10;
int diemSo[SO_MON_HOC];
nhapMang(diemSo, SO_MON_HOC);
inMang(diemSo, 5);
return 0;
}
Giới Thiệu Lập Trình


15


Tìm Kiếm
Tìm kiếm giá trị có khóa k trong mảng
Bắt đầu từ đầu (hoặc cuối), duyệt từng phần tử
Có phần tử giá trị bằng khóa trả về đúng (tìm thấy)
Hết mảng, khơng có, trả về sai (khơng tìm thấy)
bool timKiemBF{const int a[], int soPT, int k) {
for (int i = 0; i < soPT; i++)
if (a[i] == k) return true;
return false;
}
bool timKiemBW{const int a[], int soPT, int k) {
int i = soPT - 1;
while (i >= 0 && a[i] != k) i--;
return (i >= 0);
}
Giới Thiệu Lập Trình

16


Tìm Kiếm
Tìm kiếm giá trị có khóa k trong mảng
Bắt đầu từ đầu (hoặc cuối), duyệt từng phần tử
Có phần tử giá trị bằng khóa trả về chỉ số phần tử
Hết mảng, khơng có, trả về -1 (ngồi khoảng mảng)
int timKiemIF{const int a[], int soPT, int k) {

for (int i = 0; i < soPT; i++)
if (a[i] == k) return i;
return -1;
}
int timKiemIW{const int a[], int soPT, int k) {
int i = soPT - 1;
while (i >= 0 && a[i] != k) i--;
return i;
}
Giới Thiệu Lập Trình

17


Sắp Xếp Lựa Chọn
Lần lặp 1:
Tìm phần tử nhỏ nhất của mảng
Đổi chỗ với phần tử đầu tiên

Lần lặp 2:
Tìm phần tử nhỏ thứ 2 của mảng
Đổi chỗ với phần tử thứ 2

Lần lặp 3:
Tìm phần tử nhỏ thứ 3 của mảng
Đổi chỗ với phần tử thứ 3

Giới Thiệu Lập Trình

18



Sắp Xếp Lựa Chọn
Coi mảng là 2 phần:
Phần đầu: các phần tử đã được sắp xếp đúng chỗ
Phần sau: các phần tử còn lại cần được sắp xếp
Một giá trị chỉ số để xác định điểm phân cách 2 mảng

Lặp
Tìm phần tử nhỏ nhất trong mảng chưa sắp xếp
Đổi chỗ lên đầu mảng chưa sắp xếp
Tăng giá trị chỉ số lên 1

Giới Thiệu Lập Trình

19


Sắp Xếp Lựa Chọn
void sapXepLuaChon(int a[], int soPT) {
for (int i = 0; i < soPT – 1; i++) {
// tìm chỉ số phần tử có giá trị nhỏ nhất
int minI = i;
for (int j = i + 1; j < soPT; j++)
if (a[j] < a[minI]) minI = j;
// đổi chỗ lên đầu mảng chưa sắp xếp
int tmp = a[i];
a[i] = a[minI];
a[minI] = tmp;
}

}
Giới Thiệu Lập Trình

20


Thêm & Loại Dữ Liệu
Đặt vấn đề:
Sinh viên đăng ký lớp môn học
Sinh viên lần lượt đăng ký (thêm vào danh sách)
Sinh viên rút khỏi lớp môn học (loại khỏi danh sách)
Kích thước của danh sách lớp mơn học ban đầu
Số lượng sinh viên thực sự của lớp môn học

Giới Thiệu Lập Trình

21


Thêm & Loại Dữ Liệu
Thêm hay loại dữ liệu trong mảng làm thay đổi
số phần tử mảng, không thay đổi kích thước
Biến số quản lý số phần tử thực sự của mảng
Biến số này trong khoảng chỉ số hợp lệ của mảng
Chương trình phải quản lý biến số này

Thêm dữ liệu
Tăng số phần tử mảng
Phải kiểm tra mảng có đầy hay không


Loại dữ liệu
Giảm số phần tử mảng
Phải kiểm tra phần tử có trong mảng hay khơng
Giới Thiệu Lập Trình

22


Thêm Dữ Liệu
Mảng chưa sắp xếp
Thêm vào cuối cùng, sau phần tử cuối cùng
Sử dụng biến số quản lý số phần tử thực sự
Nếu mảng chưa đầy, thêm được, trả về đúng
bool them(int a[], int & soPT, int k) {
if (soPT < SO_SINH_VIEN) {
a[soPT] = k;
soPT++;
return true;
}
else {
return false;
}
}
Giới Thiệu Lập Trình

23


Loại Dữ Liệu
Mảng chưa sắp xếp

Phần tử bị loại có chỉ số là i (cần phải tìm trước)
Đổi chỗ phần tử này với phần tử cuối cùng
Sử dụng biến số quản lý số phần tử thực sự
bool loai(int a[], int & soPT, int i) {
if (soPT < 0 && i < 0 && i >= soPT) {
return false;
}
else {
// đảo chỗ a[i] và a[soPT-1] … … …
soPT--;
return false;
}
}
Giới Thiệu Lập Trình

24


×