Tải bản đầy đủ
DỮ LIỆU CÓ CẤU TRÚC

DỮ LIỆU CÓ CẤU TRÚC

Tải bản đầy đủ

Trường Đại học Điện lực - Tập đoàn Điện lực Việt Nam

.

.

HT: array[1..50] of string[30];
Trong khai báo trên:
- X là mảng một chiều có thể được xem như là một dãy số có tối đa 15 phần tử, các phần tử được
đánh số từ 1 đến 15 và có cùng kiểu nguyên.
- HT là mảng một chiều có thể được xem như là một dãy có tối đa 50 phần tử, các phần tử được
đánh số từ 1 đến 15 và có cùng kiểu xâu có tối đa 30 ký tự.
 Khai báo gián tiếp:
TYPE Tên_kiểu_mảng = ARRAY[kiểu chỉ số] OF kiểu_phần_tử;
VAR
Tên_biến_mảng : Tên_kiểu_mảng;
Trong các khai báo trên, chỉ số só thể là kiểu miền con, hoặc kiểu liệt kê vô hướng
Ví dụ 7.2: Khai báo mảng gián tiếp: khai báo mảng trực tiếp như trong ví dụ 5.1 tương đương
với cách khai báo gián tiếp như sau:
TYPE
M1 = array[1..15] of integer;
M2 = array[1..50] of string[30];
VAR
X : M1;
HT : M2;
 Truy cập đến từng phần tử của mảng 1 chiều theo cú pháp:
Tên_biến_mảng[chỉ_số]
Ví dụ 7.3: với khai báo mảng trong ví dụ 7.2
M1[1] là chỉ phần tử thứ nhất trong mảng M1
M1[i] là chỉ phần tử thứ i trong mảng M1

7.1.3. Khai báo mảng hai chiều
 Khai báo trực tiếp:
VAR Tên_biến_mảng : ARRAY[chỉ_số_hàng, chỉ_số_cột] OF kiểu_phần_tử;
Trong đó:
- chỉ_số_hàng, chỉ_số_cột: là cách tổ chức các phần tử của mảng, cách truy nhập vào các phần tử
của mảng, nó có thể là các kiểu dữ liệu đơn giản vô hướng đếm được, hữu hạn giá trị.
- kiểu_phần_tử: là kiểu dữ liệu của các phần tử của mảng, có thể là bất kỳ kiểu dữ liệu nào.
Ví dụ 7.4: Khai báo mảng trực tiếp:
VAR X : array[1..15,1..5] of integer;
HT: array[1..50,1..50] of string[30];
Trong khai báo trên:
- X là mảng hai chiều có thể được xem như là một ma trận có tối đa 75 (tối đa là 15 hàng và tối
đa 5 cột), các phần tử có kiểu nguyên.
Giáo trình Tin học đại cương

140

Trường Đại học Điện lực - Tập đoàn Điện lực Việt Nam

.

.

- HT là mảng hai chiều có thể được xem như là một ma trận có tối đa 50 hàng và 50 cột, các
phần tử có kiểu xâu có tối đa 30 ký tự.
 Khai báo gián tiếp:
TYPE Tên_kiểu_mảng = ARRAY[chỉ_số_hàng, chỉ_số_cột] OF kiểu_ phần_tử;
VAR
Tên_biến_mảng : Tên_kiểu_mảng;
* Chú ý: Trong các khai báo trên, chỉ số só thể là kiểu miền con, hoặc kiểu liệt kê vô hướng
Ví dụ 7.5: Khai báo mảng gián tiếp: khai báo mảng trực tiếp như trong ví dụ 5.1 tương đương
với cách khai báo gián tiếp như sau:
TYPE
M1 = array[1..15,1..5] of integer;
M2 = array[1..50,1..50] of string[30];
VAR X : M1;
HT: M2;


Truy cập đến từng phần tử của mảng 2 chiều theo cú pháp:

Tên_biến_mảng[chỉ_số_hàng, chỉ_số_cột]
Ví dụ 7.6: với khai báo mảng trong ví dụ 7.5
M1[1,1] là chỉ phần tử ở hàng 1, cột 1 trong mảng M1
M1[i,j] là chỉ phần tử ở hàng i, cột j trong mảng M1
* Chú ý: Thực chất mảng hai chiều là màng một chiều mà các phần tử của nó là một mảng một
chiều.

7.1.4. Các phép toán trên mảng
* Phép gán:
- Có thể thực hiện gán hai biến mảng cho nhau nếu chúng cùng kiểu dữ liệu với nhau.
Ví dụ 7.7: Với khai báo mảng sau:
TYPE dayso = array[1..50] of integer;
VAR a,b:dayso; {a và b được gọi là cùng kiểu dữ liệu với nhau}
c,d: array[1..50] of integer;
{c và d cùng kiểu dữ liệu với nhau nhưng không cùng kiểu với a và b}
Ta có thể thực hiện các phép gán sau:
a:=b;
b:=a;
c:=d;
d:=c;
- Các phần tử trong một mảng sẽ có các phép toán của kiểu dữ liệu của nó.
Ví dụ 7.8: Với khai báo mảng ở ví dụ 7.7 ta có
Các phần tử a[i] có kiểu dữ liệu là kiểu integer nên nó có mọi tính chất như một biến có kiểu
integer.
* Phép so sánh
Giáo trình Tin học đại cương

141

Trường Đại học Điện lực - Tập đoàn Điện lực Việt Nam

.

.

- Không được sử dung bất kỳ phép so sánh nào với biến có kiểu dữ liệu là kiểu mảng.
- Nếu kiểu phần tử của mảng có thực hiện được các phép so sánh thì có thể thực hiện các phép so
sánh giữa các phần tử có cùng kiểu dữ liệu với nhau.

7.1.5. Nhập và in dữ liệu của mảng
7.1.5.1. Nhập dữ liệu cho mảng
Để nhập dữ liệu cho mảng ta cũng sử dụng câu lệnh read hay readln, tuy nhiên không được
phép sử dụng các lệnh nhập dữ liệu cho biến mảng mà chỉ sử dụng cho từng phần tử trong mảng.
Do vậy để nhập dữ liệu cho mảng ta phải nhập dữ liệu cho từng phần tử trong mảng.
 Nhập dữ liệu cho mảng một chiều ta sử dụng một vòng FOR như sau:
Ví dụ cho mảng A được khai báo như sau:
Var A:array[1..100] of integer;
Nhập dữ liệu cho mảng A như sau:
For i:=1 to 100 do
Readln(A[i]);
Sử dụng vòng lặp FOR để duyệt hết mảng A, ứng với mỗi giá trị của i ta thực hiện nhập dữ liệu
cho phần tử ở vị trí thứ i trong mảng A.
 Nhập dữ liệu cho mảng hai chiều ta sử dụng hai vòng FOR lồng nhau như sau:
Ví dụ cho mảng A được khai báo như sau:
Var

A:array[1..50,1..50]

of

integer;

Nhập dữ liệu cho mảng A như sau:
For i:=1 to 50 do
For j:=1 to 50 do
Readln(A[i,j]);
Sử dụng hai vòng lặp FOR để duyệt hết mảng A, thực hiện duyệt hết theo từng hàng một, ứng
với mỗi giá trị của i ta thực hiện nhập dữ liệu cho phần tử trên hàng i, ứng với mỗi giá trị i và j ta
thực hiện nhập dữ liệu cho phần tử ở vị trí hàng i, cột j trong mảng A.
7.1.5.1. In dữ liệu mảng lên màn hình
Để in dữ liệu mảng ta cũng sử dụng câu lệnh write hay writeln, tuy nhiên không được phép
sử dụng các lệnh in dữ liệu cho biến mảng mà chỉ sử dụng cho từng phần tử trong mảng. Do vậy
để in dữ liệu mảng lên màn hình ta phải in dữ liệu từng phần tử trong mảng.


In dữ liệu mảng một chiều ta sử dụng một vòng FOR như sau:

Ví dụ cho mảng A được khai báo như sau:
Var A:array[1..100] of integer;
In dữ liệu mảng A như sau:
For i:=1 to 100 do
write(A[i]:5);

Giáo trình Tin học đại cương

142

Trường Đại học Điện lực - Tập đoàn Điện lực Việt Nam

.

.

Sử dụng vòng lặp FOR để duyệt hết mảng A, ứng với mỗi giá trị của i ta thực hiện in dữ liệu
phần tử ở vị trí thứ i trong mảng A.
 In dữ liệu mảng hai chiều ta sử dụng hai vòng FOR lồng nhau như sau:
Ví dụ cho mảng A được khai báo như sau:
Var A:array[1..50,1..50] of integer;
In dữ liệu mảng A theo dạng bảng như sau:
For i:=1 to 50 do
begin
For j:=1 to 50 do
write(A[i,j]);
writeln; {xuống dòng}
end;
Sử dụng hai vòng lặp FOR để duyệt hết mảng A, thực hiện duyệt hết theo từng hàng một,
ứng với mỗi giá trị của i ta thực hiện in dữ liệu từng phần tử trên hàng i, in hết một hàng sẽ
xuống dòng để in tiếp dòng tiếp theo, ứng với mỗi giá trị i và j ta thực hiện in dữ liệu phần tử ở
vị trí hàng i, cột j lên màn hình.
Ví dụ 7.9: Viết chương trình nhập vào một dãy số có n phần tử nguyên (1<=n<=100).
In dãy số đó lên màn hình theo hàng.
Tính tổng và trung bình cộng các phần tử trong dãy số đó. In kết quả lên màn hình.
Program vidu_7_9;
Var A: array[1..100] of integer;
S, i, n: integer;
TB:real;
Begin
Write(‘ Nhap so phan tu cua day so n = ‘); readln(n);
Writeln(‘ Nhap tung phan tu trong day so :’);
For i:=1 to n do
Begin
Write(‘a[‘,i,’]= ‘);readln(a[i]);
End;
Writeln(‘ In day so vua nhap vao la ‘);
For i:=1 to n do
Write(a[i]:5);
{Tinh tong va trung binh cong}
S:=0;
For i:=1 to n do
S:=S+a[i];
TB:=S/n;
Writeln(‘ Tong cac phan tu day so S = ‘,S);
Writeln(‘ Trung binh cong TB = ’,TB:8:2);
Readln;
End.
Giáo trình Tin học đại cương

143

Trường Đại học Điện lực - Tập đoàn Điện lực Việt Nam

.

.

Ví dụ 7.10: Viết chương trình nhập vào một ma trận nguyên cỡ mxn (1<=n, m<=20).
- In ma trận đó lên màn hình theo bảng.
- Tính tổng các phần tử âm của ma trận.
Program vidu_7_10;
Var A: array[1..20,1..20] of integer;
S, i, n: integer;
Begin
Write(‘ Nhap so hàng m = ‘); readln(m);
Write(‘ Nhap so cot
n = ‘); readln(n);
Writeln(‘ Nhap tung phan tu trong ma tran :’);
For i:=1 to m do
For j:=1 to n do
Begin
Write(‘a[‘,i,’,’,j,’]= ‘);readln(a[i,j]);
End;
Writeln(‘ In ma tran vua nhap theo dang bang: ‘);
For i:=1 to m do
Begin
For j:=1 to n do
Write(a[i,j]:5);
Writeln;
End;
{Tinh tong cac so am trong ma tran}
S:=0;
For i:=1 to m do
For j:=1 to n do
If a[i,j]<0 then
S:=S+a[i,j];
Writeln(‘ Tong cac phan tu am la S = ‘,S);
Readln;
End.

7.1.6 Một số bài toán cơ bản về mảng
7.1.6.1. Bài toán tìm kiếm trên mảng:
Tìm kiếm là một trong những bài toán cơ sở trong xử lý thông tin. Có nhiều bài toán tìm
kiếm, tuy nhiên có thể quy về tìm kiếm trên mảng như sau: Cho mảng và phần tử x có kiểu dữ
liệu cùng với kiểu dữ liệu của phần tử mảng. Hãy tìm xem có phần tử mảng nào có giá trị bằng x
hay không.

Giáo trình Tin học đại cương

144

Trường Đại học Điện lực - Tập đoàn Điện lực Việt Nam

.

.

Để giải quyết bài toán dạng này có thể sử dụng phương pháp tìm kiếm tuần tự hay tìm kiếm nhị
phân.
Thủ tục tìm kiếm tuần tự là duyệt lần lượt các phần tử mảng, so sánh giá trị của nó với x. Việc
tìm kiếm dừng khi tìm thấy hoặc đã hết mảng, tức là phát hiện ra là mảng không có giá trị khóa
nào bằng x.
Có thể triển khai thủ tục tìm kiếm trên mảng bằng một vòng lặp while, dùng cờ báo là biến
found kiểu Boolean.
Ví dụ 7.11: Viết chương trình nhập vào một dãy số thực có n phần tử và một số thực x. Kiểm tra
xem x có xuất hiện trong dãy số đó không?
Program vidu_7_11;
Var A:array[1..100] of real;
i,n:integer;
x:real;
found:boolean;
Begin
write(' Nhap so phan tu cua day so n = ');readln(n);
writeln(' Nhap tung phan tu cua day so:');
For i:=1 to n do
begin
write('A[',i,']= ');readln(A[i]);
end;
writeln('In day so vua nhap:');
For i:=1 to n do
write(A[i]:7:2);
{Tim x trong day so A}
writeln;
write(' Nhap so can tim x = ');readln(x);
found:=false;
For i:=1 to n do
if A[i]=x then
begin
found:=true;
break; {dừng vòng lặp lại}
end;
if found then
writeln(x:5:2,' co xuat hien trong day so')
else writeln(x:5:2,' khong xuat hien trong day so');
readln;
end.
Giáo trình Tin học đại cương

145

Trường Đại học Điện lực - Tập đoàn Điện lực Việt Nam

.

.

7.1.6.2. Bài toán sắp xếp dãy số tăng (giảm)
Sắp xếp cũng là một trong những bài toán cơ sở trong xử lý thông tin. Từ dãy dữ liệu ban
đầu chưa có thứ tự, cần tiến hành sắp xếp để nhận được dãy kết quả có thứ tự tăng hoặc giảm dần
theo một khóa cho trước nào đó. Bài toán quy về sắp xếp một mảng số nguyên.
Dưới đây sẽ trình bày phương pháp sắp xếp chọn trực tiếp hay còn được gọi là phương
pháp nổi bọt. Không mất tính tổng quát ta xét bài toán sắp xếp tăng, cụ thể như sau:
Mô tả
- Chọn phần tử nhỏ nhất trong dãy nguồn, xếp nó vào vị trí đầu tiên trong dãy đích. Đây là phần
tử thứ nhất và cũng là phần tử cuối cùng của dãy đích.
- Chọn phần tử nhỏ nhất trong dãy nguồn còn lại, đây là phần tử nhỏ thứ hai, xếp nó vào vị tri
thứ hai và cũng là vị trí cuối của dãy đích vào lúc này.
- Lặp lại việc này cho đến khi hết dãy nguồn.
Để tiết kiệm chỗ, ta cũng xếp dãy đích và dãy nguồn liền nhau trong mảng. Do đó, ở bước
thứ i, thao tác "xếp vào cuối dãy đích" chính là "đổi chỗ cho a[i]".
Minh hoạ:
Giả sử cần sắp xếp dãy số sau:
44 55 12 42 94 18 06 67
Sự thay đổi của dãy số qua từng bước sắp xếp như sau:
Xuất phát: 44 55 12 42 94 18 06 67
Bước 1: 06 / 55 12 42 94 18 44
Bước 2: 06 12 / 55
42 94 18 44
Bước 3: 06 12 18 / 42 94 55 44
Bước 4: 06 12 18
42 94 55 44
Bước 5: 06 12 18
42 44 / 55 94
Bước 6: 06 12 18
42 44 55 / 94
Bước 7: 06 12 18
42 44
55 67 /
Bước 8: 06 12 18
42 44 55 67

67
67
67
67
67
67
94
94

Thủ tục chi tiết
Var i,j,k: integer;
x: real;
Begin
for i:=1 to n-1 do
for j:=i+1 to n do
if a[j]“đổi chỗ a[i] và a[j] cho nhau”
End;
Ví dụ 7.12: Viết chương trình nhập vào một dãy số thực có n phần tử (1<=n<=100). Sắp xếp dãy
số theo chiều tăng dần. In lên màn hình dãy số trước và sau khi sắp xếp.
Giáo trình Tin học đại cương

146

Trường Đại học Điện lực - Tập đoàn Điện lực Việt Nam

.

.

Program vidu_7_12;
Type kieudayso = array[1..100] of real;
Var
A: kieudayso;
i, j, n: integer;
tg: real;
Begin
Write(‘ Nhap so phan tu cua day so n = ’);readln(n);
writeln(' Nhap tung phan tu cua day so:');
For i:=1 to n do
begin
write('A[',i,']= ');readln(A[i]);
end;
writeln('In day so vua nhap:');
For i:=1 to n do
write(A[i]:7:2);
{ Sắp xếp dãy số}
For i:=1 to n-1 do
For j:=i+1 to n do
If A[i]< A[j] then
Begin {hoán vị A[i] và A[j] cho nhau}
tg:=A[i];
A[i]:=A[j];
A[j]:=tg;
End;
Writeln(‘ Day so sau khi sap xep la: ‘);
For i:=1 to n do
write(A[i]:7:2);
readln;
End.

7.1.7. Một số ví dụ khác
 Ví dụ 7.13: Viết đoạn chương trình chèn một số vào dãy đã sắp tăng mà không thay đổi thứ tự
sắp xếp của dãy:
Write('Nhap so can chen k =');
Readln(k);
i:=1;
While (k>a[i]) and (i<=n) do
i:=i+1;
Writeln('Vi tri chen i=',i:2);
If i>n then
Begin
Giáo trình Tin học đại cương

147