Mảng nhiều chiều (Multi-Dimensional Array)

Một phần của tài liệu Giáo trình Pascal (Trang 44 - 49)

II. KIểU MảNG, KIểU CHUẩN

b.Mảng nhiều chiều (Multi-Dimensional Array)

Trong một số bài toán thực tế, ngời ta sử dụng các mảng nhiều hơn 1 chiều, gọi là mảng nhiều chiều.

Ví dụ 8.11: Phòng ào tạo quản lý điểm của sinh viên. Trong khoá 22 chẳng hạn, ngời ta tạo ra một mảng 2 chiều: ví dụ một chiều là số thứ tự của sinh viên, chiều còn lại là các môn học (dạng kiểu vô hớng liệt kê), ta có thể hình dung dạng của mảng ghi điểm (tên mảng là ghi_diem) nh sau:

Lu ý: Thực tế, danh sách tên sinh viên lu lại trong máy tính thờng đợc ghi bằng cách

gán mã số sinh viên (coding) cho mỗi sinh viên ngay từ năm đầu vào học.

Với ví dụ trên, muốn nhập điểm một sinh viên nào đó ta phải khai báo 2 tham số là số thứ tự sinh viên và môn học.

Tơng tự, cũng với các khoá kế tiếp theo học những môn nh vậy, ta sẽ tạo ra mảng nhiều chiều nh hình vẽ minh họa sau:

Trong trờng hợp này, muốn biết điểm một sinh viên nào đó ta phải khai báo 3 tham số: Khoá học, số thứ tự sinh viên và môn học, chẳng hạn:

ghi_diem[K22,0001,AV] nhập điểm 10,...

Khai báo cũng có 2 cách nh đối với mảng 1 chiều:

+ Khai báo gián tiếp:

TYPE

<Kiểu mảng> = ARRAY [Kiểu_chỉ_số_1,..., Kiểu_chỉ_số_n] OF <Kiểu phần tử>;

VAR

<Danh sách biến>:<Kiểu mảng>;

Ví dụ 8.12:

TYPE matrix = ARRAY [1.. 20, 1.. 30] OF integer; VAR A:matrix;

Lệnh trên khai báo một kiểu tên matrix. ây là một mảng 2 chiều, chiều thứ nhất có các chỉ số từ 1 đến 20, chiều thứ hai có các chỉ số từ 1 đến 30, tổng cộng ta có (20 x 30) phần tử số nguyên. Và ta có một biến A là biến có kiểu matrix.

Ví dụ trên cũng có thể đợc khai báo tơng đơng với:

TYPE matrix = ARRAY [1.. 20] OF ARRAY [1.. 30] OF integer; VAR A:matrix;

+ Khai báo gián tiếp:

VAR

<Danh sách biến>: ARRAY [Kiểu_chỉ_số_1,..., Kiểu_chỉ_số_n] OF <Kiểu phần tử>;

Khai báo một biến A có 5 dòng và 10 cột kiểu phần tử là Integer nh sau: VAR A: ARRAY [1.. 5, 1.. 10] OF integer;

Tơng tự nh cách truy xuất phần tử của mảng 1 chiều, mảngg nhiều chiều cũng đợc truy xuất thông qua tên biến mảng kết hợp với các chỉ số của nó đợc đặt trong cặp dấu ngoặc vuông.

Mảng 2 chiều là một ma trận, nh ví dụ trên ta có một ma trận 5 dòng và 10 cột. Các phần tử của ma trận A đợc ký hiệu là a[i,j] với i là vị trí cột và j là dòng. Khi viết a[2, 7] thì hiểu đây là phần tử ở dòng 2 và cột 7.

Trong Pascal, ta có thể viết a[i,j] thành a[i] [j] với ý nghĩa hoàn toàn nh nhau.

Chú ý: Trên nguyên tắc, ta có thể khai báo một mảng có đến 255 chiều. Tuy vậy, một điều cần lu ý là kích thớc bộ nhớ của máy tính có hạn nên thờng chỉ khai báo mảng từ 1 đến 3 chiều. Khai biến quá nhiều thì phải cần máy lớn hơn.

Chẳng hạn khi báo 1 mảng [1.. 10] các phần tử số nguyên đã lấy 10 bytes bộ nhớ - Mảng 2 chiều 10 x 10 = 100 bytes bộ nhớ. - Mảng 3 chiều 10 x 10 x 10 = 1 000 bytes bộ nhớ - Mảng 4 chiều 10 x 10 x 10 x 10 = 10 000 bytes bộ nhớ - Mảng 5 chiều 10 x 10 x 10 x 10 x 10 = 100 000 bytes bộ nhớ - v.v... Ví dụ 8.13:

Viết một chơng trình Pascal để đọc một bảng các số thực đợc nhập vào máy tính dới dạng một mảng 2 chiều. Tính tổng các giá trị số theo hàng và theo cột. Kết quả đợc in ra màn hình theo vị trí hàng và cột tơng ứng.

Trớc tiên, ta bắt đầu bằng định nghĩa các biến: (adsbygoogle = window.adsbygoogle || []).push({});

table = mảng 2 chiều chứa số thực dới dạng bảng gồm các số nhập và kết quả nrows = một biến số nguyên chỉ số hàng

ncols = một biến số nguyên chỉ số cột row = một số đếm nguyên chỉ số hàng col = một số đếm nguyên chỉ số cột

ể đơn giản, chúng ta giả sử rằng kích thớc số liệu nhập vào bảng tính không vợt quá 10 hàng và 10 cột. Ta sẽ thêm vào 1 hàng cộng phía dới và 1 cột cộng bên phải vào bảng để ghi kết quả tính cộng các phần tử hàng và cột tơng ứng. Nh vậy, mảng 2 chiều của chúng ta sẽ trở thành mảng sẽ đợc in ra có số hàng là (nrows + 1) và số cột là (ncols +1). Do vậy, ta phải khai báo biến table là 1 mảng 2 chiều số nguyên có tối đa 11 cột và 11 hàng.

ể dễ theo dõi chơng trình, ta thực hiện cấu trúc module khi viết chơng trình bằng cách tiến hành làm các thủ tục procedure cho đọc số liệu, tính tổng các phần tử theo hàng, tính tổng các phần tử theo cột và in ra màn hình bảng kết quả. Các thủ tục này sẽ có tên tơng ứng là readinput, rowsums, columsums và writeoutput.

Thuật toán logic yêu cầu cho mỗi thủ tục là cách khai báo thẳng trớc (straightforward), chú ý rằng trong mỗi thủ tục ta có một vòng lặp đôi (double loop). Ví dụ, để đọc số liệu ở bảng gốc, ta sẽ phải làm một vòng lặp đôi sau:

FOR row:= 1 TO nrows DO BEGIN

Writeln; END;

Câu lệnh Writeln để báo chơng trình nhảy tới dòng kế.

Tơng tự, vòng lặp sau đợc viết để tính tổng các phần tử theo hàng: FOR row:= 1 TO nrows DO

BEGIN

table [row, ncols + 1]:= 0; FOR col:= 1 TO ncols DO

table [row, ncols + 1]:= table [row, ncols + 1] + table [row, col]; END;

Tơng tự, cấu trúc vòng lặp đôi cũng đợc dùng để tính tổng các phần tử cột và in ra bảng kết quả cuối cùng.

Sau đây là chơng trình Pascal của bài toán trên: PROGRAM Tongbang;

{đọc một bảng số, tính tổng từng cột và hàng của cá bảng} VAR

row, col: 1.. 11; nrows, ncols: 1.. 10;

table: ARRAY [1.. 11, 1.. 11] OF real;

PROCEDURE Rowsums; {cộng các phần tử theo cột bên trong mỗi hàng} BEGIN

FOR row:= 1 TO nrows DO BEGIN

table [row,ncols+1]:= 0; FOR col:= 1 TO ncols DO

table[row, ncols+1]:= table[row, ncols+1] + table[row,col]; END;

END;

PROCEDURE Columnsums; {cộng các phần tử theo hàng bên trong từng cột} BEGIN

FOR col:= 1 TO ncols DO BEGIN

table [nrows+1, col]:= 0; FOR row:= 1 TO nrows DO

table[nrows+1,col]:= table[nrows+1,col] + table[row,col]; END;

END;

PROCEDURE Readinput; {đọc các phần tử của bảng} BEGIN

Write(' Nhập số hàng (1.. 10) ? ');Readln(nrows); Write(' Nhập số cột (1.. 10) ? ');Readln(ncols); FOR row:= 1 TO nrows DO

BEGIN (adsbygoogle = window.adsbygoogle || []).push({});

Writeln (' Nhập số liệu hàng số, row:2');

FOR col:= 1 TO ncols DO readln(table [row, col] ); END;

END;

PROCEDURE Writeoutput; {In ra bảng số liệu và kết quả tính tổng} BEGIN

Writeln('Bảng số liệu và kết quả tính tổng các phần tử theo hàng và cột '); Writeln(‘============================================= ‘); Writeln;

FOR row:= 1 TO nrows + 1 DO BEGIN

FOR col:= 1 TO ncols+1 DO Write (table [row,col]: 6: 1); Writeln;

END; END;

BEGIN {Thân chơng trình chính} Readinput;

Rowsums; Columnsums; Writeoutput;

END. {Chấm dứt chơng trình} Giả sử, ta có bảng số liệu sau:

2.5 -6.3 14.7 4.0 10.8 12.4 -8.2 5.5 10.8 12.4 -8.2 5.5

-7.2 3.1 17.7 -9.1

Khi chạy chơng trình, ta có (số có gạch dới là số của ngời thử chơng trình): Nhập số hàng (1.. 10 ) ? 3 Nhập số cột (1.. 10) ? 4 Nhập số liệu hàng số 1 2.5 -6.3 14.7 4.0 Nhập số liệu hàng số 2 10.8 12.4 -8.2 5.5 Nhập số liệu hàng số 3 -7.2 3.1 17.7 -9.1

Chơng trình sẽ tính tổng các giá trị ở hàng và cột, xong in ra màn hình kết quả: Bảng số liệu và kết quả tính tổng các phần tử theo hàng và cột

2.5 -6.3 14.7 4.0 14.9 10.8 12.4 -8.2 5.5 20.5 10.8 12.4 -8.2 5.5 20.5 -7.2 3.1 17.7 -9.1 4.5 6.1 9.2 24.2 0.4 0.0

Một phần của tài liệu Giáo trình Pascal (Trang 44 - 49)