Tài liệu

Lý thuyết: Kiểu mảng trang 53 SGK Tin học 11

Huy Erick

Kiểu mảng một chiều Mảng một chiều là một dãy hữu hạn các phần tử cùng kiểu. Mỗi phần tử trong mảng được đánh dấu bởi một chỉ số. Để mô tả mảng một chiều,...

Kiểu mảng một chiều

Mảng một chiều là một dãy hữu hạn các phần tử cùng kiểu. Mỗi phần tử trong mảng được đánh dấu bởi một chỉ số. Để mô tả mảng một chiều, ta cần xác định kiểu của các phần tử và cách đánh số các phần tử.

Trong ngôn ngữ lập trình, để xây dựng và sử dụng mảng một chiều, ta cần tuân thủ các quy tắc sau:

  • Xác định tên kiểu mảng một chiều
  • Xác định số lượng phần tử của mảng
  • Xác định kiểu dữ liệu của phần tử
  • Khai báo biến mảng
  • Tham chiếu đến phần tử

Mỗi phần tử trong mảng có thể được truy cập bằng cách sử dụng tên mảng cùng với chỉ số tương ứng của phần tử. Mảng là một kiểu dữ liệu có cấu trúc, rất hữu ích và cần thiết trong nhiều chương trình.

Khai báo

Có hai cách để khai báo mảng một chiều:

Cách 1: Khai báo trực tiếp biến mảng một chiều:

var : array[kiểu chỉ số] of ;

Cách 2: Khai báo gián tiếp biến mảng qua kiểu mảng một chiều:

type  = array[kiểu chỉ số] of ;
var : ;

Trong đó:

  • Kiểu chỉ số thường là một đoạn số nguyên liên tục có dạng n1...n2 với n1, n2 là các số nguyên xác định chỉ số đầu và chỉ số cuối (n1 n2).
  • Kiểu phần tử là kiểu dữ liệu của từng phần tử trong mảng.

Ví dụ, các khai báo sau đây là hợp lệ với mảng một chiều:

type
ArrayReal = array[-100..200] of real;
ArrayBoolean = array[-n+1..n+1] of boolean;
ArrayInt = array[-100..0] of integer;

Lưu ý:

  • Để tham chiếu đến phần tử của mảng một chiều, ta sử dụng tên mảng kèm theo chỉ số, được viết trong cặp dấu ngoặc [].

Ví dụ về bài toán

Đối với ví dụ 1 về bài toán "Tìm phần tử lớn nhất của dãy số nguyên", chương trình được mô tả như sau:

Program timMax;
uses crt;
const
Nmax := 250;
type
arrint = array[1..Nmax] of integer;
var
N, i, Max, csmax: integer;
A: arrlnt;
Begin
clrscr;
write ('Nhap so luong phan tu cua day so, N- ');
readln (N);
for i:= 1 to N do
begin
write ('Phan tu thu ' ,i,' = ' ) ;
readln (A [ i ] );
end;
Max: =A (10); csmax:= 1;
for i:= 2 to N do if A[i] > Max then
begin
Max:= A[i]; csmax:= i;
end;
writeln('Gia tri cua phan tu Max: ', Max);
write In(’Chi so cua phan tu Max: ' , csmax); readln
End

Phần tử lớn nhất của dãy được tìm thấy là 15 và có chỉ số là 1.

Kiểu mảng một chiều

Từ chương trình này, chúng ta rút ra được một số điều cơ bản cần lưu ý, đó là:

  • Sử dụng mảng có kiểu phần tử là số nguyên để biểu diễn một dãy hữu hạn số nguyên và cách khai báo mảng này.
  • Câu lệnh for-do thể hiện một nhiệm vụ trong bước 1 của thuật toán, dùng để nhập các phần tử của mảng. Số phần tử thực sự của mảng do người dùng nhập vào.
  • Câu lệnh for-do thể hiện vòng lặp (gồm bước 3 và 4 trong thuật toán), dùng để duyệt tuần tự từng phần tử trong mảng để tìm phần tử lớn nhất.

Đối với ví dụ 2 về bài toán "Sắp xếp dãy số nguyên bằng thuật toán đổi chỗ", chương trình được mô tả như sau:

program sapxep;
uses crt;
const Nmax = 250;
type
ArrInt = array[1..Nmax] of integer;
var
N.I,j,t: integer;
A: Arrlnt;
Begin
clrscr;
write ( ' Nhap so luong phan tu cua day so, N-');
readln(N); for i:= 1 to N do begin
write(' Phan tu thu',i,' = '); readln(A[i]);
end,
for j:= N downto 1 do begin
for i:= 1 to j-1 do if A[i] > A[i+1] then
begin
t: = A [ i ] , A[i]:= A[i+1];
A [ i +1 ] : = t;
end;
end;
writeln('Day so duoc sap xep la:'); for i:= 1 to N do write(A[i]:4);
readln
End.

Sau khi chạy chương trình, dãy số được sắp xếp là: 3 5 6 7 9.

Sắp xếp dãy số nguyên bằng thuật toán đổi chỗ

Từ chương trình này, chúng ta rút ra được một số điều cơ bản cần lưu ý, đó là:

  • Quá trình sắp xếp bằng thuật toán đổi chỗ thể hiện theo từng lượt. Sau mỗi lượt, phần tử lớn nhất được đặt đúng vị trí ở cuối dãy. Mỗi lượt có ít nhất một phần tử được đặt đúng vị trí. Trong thuật toán, ta cần thực hiện bao nhiêu lượt như vậy và lần lặp này thực hiện trên đoạn nào của dãy số? Giá trị của j chính là chỉ số phần tử cuối trong đoạn được duyệt của lượt. Đây chính là câu lệnh for j: N downto 2 cho biến j chạy từ N về 2.
  • Mỗi lượt bao gồm việc thực hiện một số thao tác: so sánh một phần tử với phần tử đứng ngay sau nó để xử lí, bắt đầu từ phần tử đầu tiên trong dãy đến phần tử thứ j. Thao tác so sánh để quyết định xử lí (đổi chỗ hai phần tử) được lặp một số lần. Đây chính là câu lệnh lặp mà chương trình dùng để thể hiện mỗi lượt.

Đối với ví dụ 3 về bài toán "Tìm kiếm nhị phân", thuật toán và chương trình được mô tả như sau:

Thuật toán:

  • Bước 1: Nhập N, các số hạng a1, a2... aN và khóa k
  • Bước 2: Dau — 1, Cuoi -N;
  • Bước 3: Giua —[ Dau + Cuoi]/2
  • Bước 4: Nếu A[Giua] = k thì thông báo chỉ số Giua rồi kết thúc;
  • Bước 5: Nếu A[Giua] > k thì đặt Cuoi= Giua-1 rồi chuyển đến bước 7;
  • Bước 6: Nếu Nếu A[Giua] ≤ k Dau
  • Bước 7: Nếu Dau > Cuoi thì thông báo dãy A không có số hạng có giá trị bằng k rồi kết thúc;
  • Bước 8: Quay lại bước 3.
program TK_nhiphan;
uses crt;
const
Nmax = 250;
type
Arrlnt = array[1..Nmax] of integer;
var
N, i0 k: integer;
Dau, Cuoi, Giua: integer;
A: Arrlnt;
Tim__thay: boolean;
Begin
clrscr;
write('Nhap so luong phan tu cua day so, N=' ) ;
readln (N) ;
writeln('Nhap cac phan tu cua day so tang:');
for i:=1 to N do
begin
write('Phan tu thu ',i,'=1);
readln (A [ i ] );
end;
write('Nhap vao gia tri k =');
readln (k) ;
Dau:= 1, Cuoi : = N;
Tim__thay : = false ;
while (Dau = Cuoi) and not (Tim_thay) do
begin
Giua:= (Dau+Cuoi) div 2;
if A[Giua] = k then Tim_thay:= true
else
if A[Giua] > k then Cuoi:= Giua-1 else Dau:= Giua + 1;
End;
if Tim_thay then writeln('Chi so tim duoc la:', Giua)t else writeln(Khong tim thay’);
readln
End.

Sau khi chạy chương trình, với giá trị phần tử của dãy là 3, 5, 7, 9, 12 và giá trị k = 9, chương trình sẽ thông báo "Chỉ số tìm được là 4".

Tìm kiếm nhị phân

Từ chương trình này, chúng ta rút ra được một số lưu ý như sau:

  • Phần cơ bản của chương trình thể hiện qua một cấu trúc lặp (chưa biết trước số lần lặp).
  • Cần ghi nhận sự kiện tìm thấy, có thể dùng một biến logic Tim-thay để ghi nhận. Khi chưa tìm kiếm, biến này được khởi tạo là False. Khi tìm thấy, giá trị của biến là True. Điều này giúp xác định điều kiện lặp.
  • Điều kiện lặp thể hiện sự kiện chưa tìm thấy hoặc không gian tìm kiếm đã rỗng bằng một biểu thức logic.
  • Khi kết thúc lặp, giá trị của biến logic Tim-thay cho biết liệu tìm thấy hay không. Sau cấu trúc lặp, ta sử dụng câu lệnh rẽ nhánh theo giá trị của Tim-thay để thông báo kết quả.
  • Trong trường hợp tìm thấy, cần đưa ra kết quả chi tiết hơn, thông báo chỉ số của phần tử có giá trị k. Khi tìm thấy, sự kiện này được ghi nhận ngay lập tức (sau khi so sánh phần tử giữa được chọn với k), sau đó, điều kiện lặp được kiểm tra và quá trình lặp dừng lại. Do đó, giá trị của biến Giua cho biết chỉ số của phần tử cần tìm.

Kiểu mảnh hai chiều

  • Mảng hai chiều là một bảng các phần tử cùng kiểu, trong đó mỗi phần tử lại là một mảng một chiều.
  • Với kiểu mảng hai chiều, ngôn ngữ lập trình định nghĩa các quy tắc và cách thức cho phép xác định:
    • Tên kiểu mảng hai chiều
    • Số lượng phần tử của từng chiều
    • Kiểu dữ liệu của phần tử
    • Cách khai báo biến
    • Cách tham chiếu đến phần tử

Ví dụ, bảng cửu chương có thể được khai báo như sau:

var B: array[1..9, 1..10] of integer;

hoặc có thể khai báo ngắn gọn hơn:

var B: array[1..9, 1..10] of integer;

Khai báo

Có hai cách để khai báo mảng hai chiều:

Cách 1: Khai báo trực tiếp biến mảng hai chiều:

var : array[kiểu chỉ số dòng, kiểu chỉ số cột] of ;

Cách 2: Khai báo gián tiếp biến mảng qua kiểu mảng hai chiều:

type  = array[kiểu chỉ số dòng, kiểu chỉ số cột] of ;
var : ;

Trong đó:

  • Kiểu chỉ số dòng và kiểu chỉ số cột là hai kiểu chỉ số độc lập với nhau.
  • Kiểu phần tử là kiểu dữ liệu của từng phần tử trong mảng.

Lưu ý:

  • Giống như khi khai báo kiểu dữ liệu mảng một chiều, người lập trình cần phải xác định kiểu của các phần tử tạo nên mảng và kiểu chỉ số.
  • Các thao tác nhập, xuất hay xử lí mỗi phần tử của mảng phải tuân theo quy định kiểu phần tử của mảng.
  • Thực hiện thao tác nhập, xuất hay xử lí tuần tự trên các phần tử của mảng hai chiều thường sử dụng cấu trúc lặp for-do lồng nhau.

Đối với ví dụ 1 về bài toán "Tính và đưa ra màn hình bảng cửu chương", chương trình được mô tả như sau:

program Bangcuuchuong;
uses crt;
var
B: array[1..9, 1..10] of integer;
i, j: integer;
Begin
clrscr;
for i:=1 to 9 do
    for j:=1 to 10 do
        B[i, j]:= i*j;
for i:=1 to 9 do 
begin
    for j:=1 to 10 do 
        write(B[i,j]:4) 
    writeln;
end;
readln
End.

Khi chạy chương trình, kết quả sẽ hiển thị bảng cửu chương từ 1 đến 9.

Bảng cửu chương

Đối với ví dụ 2 về bài toán "Lập chương trình nhập vào từ bàn phím các phần tử của mảng hai chiều B gồm 5 dòng, 7 cột với các phần tử là các số nguyên", chương trình được mô tả như sau:

Begin
clrscr;
write('Nhap cac phan tu cua mang theo dong:');
for i := 1 to 5 do
begin
    for j:= 1 to 7 do 
        read (b [ i, j ] );
    writeln;
end;
write('Nhap vao gia tri k = '); 
readln(k); 
d: = 0 ;
writeln('DS cac phan tu mang nho hon ', k, ':');
for i:=1 to 5 do
    for j:= 1 to 7 do 
        if b[i,j]  k then 
        begin
            write(b[i,j],' '); 
            d:= d+1; 
        end;
if d=c then 
    writeln('khong co phan tu nao nho hon', k);
readln
End.

Sau khi chạy chương trình, nhập các phần tử của mảng và giá trị k = 7, chương trình sẽ hiển thị danh sách các phần tử nhỏ hơn 7.

Nhập phần tử của mảng hai chiều

Từ chương trình này, chúng ta rút ra được một số lưu ý như sau:

  • Quá trình nhập phần tử của mảng được thể hiện qua vòng lặp for-do lồng nhau.
  • Giá trị của biến d được tăng lên mỗi khi phát hiện một phần tử trong mảng nhỏ hơn k.
  • Nếu không có phần tử nào nhỏ hơn k, chương trình sẽ thông báo không có phần tử nào thỏa điều kiện.
1