Chương II
CÁC KIẾN THỨC CƠ BẢN.
I. Thuật toán:
1. Khái niệm thuật toán và đặc trưng của nó:
Giả sử nhằm đảm bảo vệ sinh an toàn thực phẩm chúng ta muốn đóng
gói kẹo dừa trên một dây chuyền tự động thay cho gói kẹo bằng tay như hiện
nay. Để giải quyết bài toán này, chúng ta phải thiết kế và chế tạo ra một thiết
bò cơ - điện tử thực hiện các công đoạn từ khâu chiết khối kẹo còn nóng sang
thiết bò đóng gói cho đến khâu đưa hộp kẹo ra khỏi băng chuyền. Thiết bò này
được điều khiển tự động bằng máy tính và gồm các thao tác:
Bước 0: Khởi động việc đếm số viên kẹo (sovienkeo:=0). Qua bước 1.
Bước 1: Nhận khối kẹo còn nóng từ chảo nấu. Nếu khối kẹo vừa nhận có trọng lượng khác 0
thì qua bước 2, bằng không qua bước 11.
Bước 2: Trọng lượng của khối kẹo khác 0? Đúng: Qua bước 3 – Sai: Qua bước 1.
Bước 3: Đùn ép và chia cắt khối kẹo thành viên thích hợp. Qua bước 4
Bước 4: Đưa viên kẹo lên khuôn ép đònh hình. Qua bước 5
Bước 5: Lấy viên kẹo ra khỏi khuôn ép và đặt lên băng giấy đúng vò trí qui đònh. Qua bước
6.
Bước 6: Cắt băng giấy vừa viên kẹo và ép gói theo dạng qui đònh. Qua bước 7.
Bước 7: Đẩy ép viên kẹo vào hộp. Qua bước 8.
Bước 8: Đếm số viên kẹo đã đặt vào hộp (sovienkeo:=sovienkeo+1). Nếu số viên kẹo còn
nhỏ hơn 100 thì trở về bước 2, ngược lại qua bước 9.
Bước 9: Đưa hộp kẹo ra khỏi băng chuyền. Qua bước 10:
Bước 10: Đặt hộp kẹo rổng vào vò trí cũ. Khởi động lại việc đếm số viên kẹo đã đặt vào
hộp. Trở về bước 2.
Bước 11: Dừng máy.
Qui trình trên cho phép ta/máy thực hiện chính xác, đúng từng bước một công
việc đã giao – từ lúc bắt đầu (nhận khối kẹo nóng/khởi tạo biến đếm) đến lúc
kết thúc công việc (dừng máy). Một số công đoạn có thể sẽ phải lập đi lập lại
nhiều lần. Với mỗi khối kẹo đã nhận qui trình cho ra kết quả rõ ràng là các
hộp kẹo. Qui trình trên có qui đònh thứ tự bắt buộc đối với các thao tác. Thứ tự
đó không thể thay đổi được. Mỗi công đoạn trong qui trình trên đều có thể
thực hiện một cách tương ứng bởi con người (dó nhiên là mất thời gian hơn,
nguy hiểm hơn, ...).
Không phải bài toán nào cũng có thể đưa ra một qui trình giải quyết như vậy.
Tuy nhiên ví dụ trên cũng đủ dẫn chúng ta đến với khái niệm:
24
Thuật toán:
Một giải thuật (hay thuật toán) là một dãy hữu hạn, có thứ tự các chỉ thò nhằm
giải quyết một bài toán đảm bảo được 6 tính chất đặc trưng cơ bản sau đây:
o Một giải thuật bắt đầu bằng những chỉ thò nhập dữ liệu đầu vào (inputs).
Các dữ liệu nhập này sẽ được xử lí bởi những chỉ thò tiếp theo sau của giải
thuật.
o Các qui tắc xử lí (processing rules) nêu ra trong giải thuật phải chính xác
và không mơ hồ sao cho có thể thực hiện được đúng các qui tắc đó.
o Mỗi chỉ thò phải đủ căn bản sao cho, về nguyên tắc, có thể hoàn thành bởi
con người – và bằng tay – trong hữu hạn thời gian.
o Giải thuật phải đủ tổng quát để giải được tất cả các bài toán có dạng như
yêu cầu chứ không chỉ cho một tập đặc biêït các giá trò đầu vào.
o Tổng thời gian dùng để thực hiện mọi bước của giải thuật phải hữu hạn .
Có thể có một số chỉ thò trong các bước giải sẽ được lập đi lập lại nhiều
lần nhưng số lần lập phải hữu hạn.
o Giải thuật phải cho ra kết quả (outputs). Nói cách khác giải thuật phải có
tính dừng.
o Các thao tác và cấu trúc điều khiển cơ sở.
Để hiện thực được các thuật toán ta cần thiết kế một số thao tác cơ bản cần thiết
cho việc thực thi từng bước của thuật toán trên một máy tính giả đònh.
Các thao thác căn bản:
Tên thao tác Kí hiệu Ý nghóa
Thao tác nhập
input(x)
Thao tác này cho phép xem x như một biến chờ
được nhập dữ liệu từ một thiết bò nhập chuẩn
nào đó.
Thao tác xuất
output(x)
Thao tác này cho phép xuất giá trò hiện tại của
x ra một thiết bò xuất chuẩn nào đó.
Thao tác gán trò
x:=y
Thao tác này được thực hiện từ vế phải qua vế
trái nhằm gán giá trò hiện tại của y cho x.
Thao tác trả về một
giá trò
Return x
Thao tác này cho phép trả về giá trò hiện tại của
x cho một thiết bò nào đó.
Các thao tác số học
cơ bản hoặc các tác
vụ căn bản
+ - * div. ...
Các cấu trúc điều khiển:
Để biểu diễn quá trình thực hiện một thuật toán, người ta có thể chỉ mô tả tuần
tự các tác vụ của thuật toán kèm theo các chỉ thò so sánh và các lệnh nhảy (jump hoặc
goto) là đủ. Chẳng hạn như trong ví dụ trên, ở bước 8 ta có một chỉ thò so sánh
25
(sovienkeo<100 ?) và một lệnh nhảy (Trở về bước 2 | Qua bước 9). Đó là cách mà các ngôn
ngữ lập trình cấp thấp như ASSEMBLY (hoặc thậm chí 1985 ANS BASIC –American
National Basic) vẫn dùng. Tuy nhiên mô tả thuật toán trong một cấu trúc như vậy làm
cho thuật toán trở nên khó đọc, khó hiểu và rất dễ trở nên rối rắm, nhiều nhầm lẫn một
khi có quá nhiều lệnh nhảy tới lui trong các bước thực hiện. Để làm cho việc mô tả
thuật toán trở nên trong sáng hơn người ta thấy rằng trong mọi trường hợp hoàn toàn có
thể thay lệnh nhảy (jmp hoặc goto) bằng (và chỉ cần như vậy là đủ) ba cấu trúc điều
khiển sau đây:
Cấu trúc tuần tự:
Trong cấu trúc điều khiển này các chỉ thò được mô tả thành một dãy tuần tự và
được thực thi đúng như theo thứ tự mà chúng được mô tả. Nói cách khác lệnh nhảy đến
bước kế tiếp liền kề sau bước đóù là không cần thiết phải nêu ra một cách tường minh.
Nếu một dãy tuần tự các chỉ thò được xem như một khối thống nhất phải thực hiện đầy
đủ, hoàn tất thì chúng phải được đánh đấu ở đầu khối và ở cuối khối, chẳng hạn bằng
một cặp từ khoá begin / end.
Cấu trúc lựa chọn:
Cấu trúc này có cú pháp như sau:
IF <biểu thức lôgic=1> THEN TacVu1 ELSE TacVu2
Cấu trúc này buộc trước tiên phải kiểm tra một điều kiện <biểu thức lôgic>.
Nếu giá trò của biểu thức này là đúng thì TacVu1 được thực hiện, bằng không TacVu2
sẽ được thực hiện. Cú pháp này cho phép “rẽ nhánh” chương trình, cho phép chỉ
TacVu1 hoặc (XOR) TacVu2 được thực hiện tuỳ theo giá trò của <biểu thức lôgic> tại
thời điểm chương trình đang được thực thi (in run time).
Ví dụ: IF (Sốlượng >0) THEN
LàmTiếp
ELSE
Dừng
Cấu trúc lặp:
Cấu trúc này có cú pháp như sau:
WHILE <biểu thức lôgic=1> DO TacVu
Cấu trúc này buộc trước tiên phải kiểm tra một điều kiện <biểu thức lôgic>.
Nếu giá trò của biểu thức này là đúng thì TacVu được thực hiện. Sau khi TacVu thực
hiện xong thì <biểu thức lôgic> lại được kiểm tra, nếu <biểu thức logic> còn đúng thì
TacVu lại được thực hiện, và .v.v. cho đến khi việc kiểm tra <biểu thức logic> cho thấy
<biểu thức lôgic> không còn đúng thì chấm dứt lập lại TacVu. Cấu trúc này cho phép
“lập lại” TacVu nhiều lần tuỳ theo giá trò của <biểu thức lôgic>. Rõ ràng để đảm bảo
tính hữu hạn và tính dừng của chương trình thì trong khi thực hiện TacVu phải có cách
làm thay đổi giá trò của <biểu thức lôgic> để chương trình có thể thoát ra khỏi vòng lặp
sau một số lần lặp nào đó.
26
Ví dụ:
I:=2
WHILE (I
≤
5) DO
Begin
Output (i
2
)
i:=i+1
End
Vòng lặp WHILE trong ví dụ này thực hiện khối chỉ thò được bao trong cặp
Begin ... End bốn lần (đưa ra thiết bò xuất chuẩn các số chính phương 4, 9, 16, 25).
o Các hình thức biểu diễn thuật toán.
o Lưu đồ thuật toán (flow chart) : Dùng các sơ đồ dòng chảy trong đó kết
hợp các đầu nối, các kí hiệu khối tác vụ và các mũi tên để biểu diễn quá
trình thực hiện của thuật toán.
Các kí hiệu khối tác vụ được qui đònh trong bảng sau:
Hình dạng Dùng để Ví dụ
Biểu diễn tác vụ xử lí
của máy tính.
Một xử lí được đònh
nghóa trước
Gọi thường
trình xử lí màn
hình
Input; Output
input (N)
Quyết đònh rẽ
nhánh
So <7
Bắt đầu hoặc kết thúc
thủ tục
BEGIN
Đầu nối
1
2
Kí hiệu hướng dòng chảy
27
Tính giai thừa
của N
Ví dụ về lưu đồ giải phương trình bậc nhất dạng ax+b=0
BEGIN
input(a,b) a
≠
0 False b=0 vô
nghiệm
True
x=-b/a vô số nghiệm
END
o Mã giả (pseudo code) : Mã giả dùng một số từ khoá, tương tự như các
từ khoá dùng trong một ngôn ngữ lập trình nào đó – chẳng hạn ngôn
ngữ Pascal – để mô tả quá trình thực hiện giải thuật. Ngoài các từ
khoá ứng với các cấu trúc vừa nêu trên các từ khoá tựa–Pascal sẽ
dùng trong giáo trình này là:
1
Procedure Chỉ đònh tên của thủ tục/ giải thuật.
FOR i:=giá trò đầu TO giá trò cuối DO Công Việc
Lập lại Công Việc mỗi lần i thay đổi giá trò (từ giá
trò đầu đến Giá Trò cuối), mỗi lần thực hiện xong
Công Việc giá trò i tự động tăng lên một đơn vò.
Ví dụ 1: Sau đây là đoạn mã giả tương ứng với lưu đồ giải phương trình dạng
ax+b=0 nói trên.
Procedure GiaiPhuongTrinhBacNhat
input(a)
input(b)
IF (a
≠
0) THEN
Output (x= -b/a)
ELSE
IF (b=0) THEN
Output(Phuong trinh co vo so nghiem)
ELSE
Output(Phuong trinh vo nghiem)
Ví dụ 2: Thuật toán tìm phần tử lớn nhất trong một dãy hữu hạn.
1
Chú ý rằng mã giả độc lập đối với mọi ngôn ngữ lập trình, do đó không cần tuân thủ cú pháp
nghiêm ngặt như của một ngôn ngữ lập trình nào. Mọi chỉ thò nếu cần thiết đều có thể dùng được trong
mã giả miễn là mô tả được bản chất thuật toán của bài toán cần giải.
28