Lập trình phát triển chương trình
Trang 1KỸ THUẬT PHÁT TRIỂN CHƯƠNG TRÌNH
NỘI DUNG
Phát triển chương trình bằng phương pháp tinh
chỉnh dần từng bước.
Định nghĩa và sử dụng hàm trong ngôn ngữ C
1
? Sức mạnh của đệ quy là gì?
Lời giải của bài toán T gọi là đệ quy nếu nó được thực hiện bằng lời giải của bài toán T’ có dạng giống T
Giải thuật tương ứng với lời giải đệ quy gọi là giải thuật
đệ quy
Biểu diễn giải thuật đệ quy: trong chương trình cần có thủ tục hay chương trình con
có lời gọi đến P.
• 5! = 5 * 4 * 3 * 2 * 1
• Chú ý rằng:
–5! = 5 * 4!
–4! = 4 * 3!
• Có thể thực hiện gọi đệ qui
• Điều kiện kết thúc gọi đệ qui: 1! = 0! = 1
–2! = 2 * 1! = 2 * 1 = 2;
–3! = 3 * 2! = 3 * 2 = 6;
? Bài toán nào có thể dùng đệ quy?
Hàm đệ quy thường được viết theo thuật toán sau:
if (trường hợp suy biến) { Lời giải bài toán trong trường hợp suy biến;
} else { Gọi đệ quy tới hàm với giá trị khác của tham số;
}
Trang 2 Ví dụ 1 Hàm giai thừa
⎩
⎨
⎧
>
−
=
=
0 ),
1 (
*
0 ,
1 )
(
n if n
Fac n
n if n
Fac
function Fac(i: integer): integer;
begin
if i <=1 then Fac := 1 else Fac:= i * Fac(i − 1);
end;
5
5!
(a) Sequenc e of rec ursive c alls (b) Values returned from eac h recursive c all.
Final value = 120 5! = 5 * 24 = 120 is returned 4! = 4 * 6 = 24 is returned
2! = 2 * 1 = 2 is returned 3! = 3 * 2 = 6 is returned
1 returned
5 * 4!
1
4 * 3!
3 * 2!
2 * 1!
5!
5 * 4!
1
4 * 3!
3 * 2!
2 * 1!
fig05_14.c (Part 1 of 2)
1 /* Fig 5.14: fig05_14.c
2 Recursive factorial function */
3 #include <stdio.h>
4
5 long factorial( long number ); /* function prototype */ 6
7 /* function main begins program execution */ 8 int main() 9 {
10 int i; /* counter */ 11
12 /* loop 10 times During each iteration, calculate 13 factorial( i ) and display result */ 14 for ( i = 1 ; i <= 10 ; i++ ) { 15 printf( "%2d! = %ld\n" , i, factorial( i ) ); 16 } /* end for */ 17
18 return ; /* indicates successful termination */ 19
20 } /* end main */ 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 10! = 3628800 22 /* recursive definition of function factorial */
23 long factorial( long number )
24 {
25 /* base case */
26 if ( number <= 1 ) {
27 return ;
28 } /* end if */
29 else { /* recursive step */
30 return ( number * factorial( number - 1 ) );
31 } /* end else */
32
33 } /* end function factorial */
Trang 3 Ví dụ 2 Dãy số Fibonacci
Bài toán:
thỏ con (1 đực, 1 cái).
được một cặp mới.
bao nhiêu cặp?
9
function Fib(n: integer):integer;
begin
if n = 0 then Fib := 0 else
if n = 1 then Fib := 1 else
Fib := Fib(n−1) + Fib(n−2);
end;
⎩
⎨
⎧
>
− +
−
≤
=
2 ),
2 ( )
1 (
2 ,
1 )
(
n if n
Fib n
Fib
n if n
Fib
Gọi function fibonacci
f( 3 )
f( 1 ) f( 2 )
return 1 return 0
+ return
1 /* Fig 5.15: fig05_15.c
2 Recursive fibonacci function */
3 #include <stdio.h>
4
5 long fibonacci( long n ); /* function prototype */
6
7 /* function main begins program execution */
8 int main()
9 {
10 long result; /* fibonacci value */
11 long number; /* number input by user */
12
13 /* obtain integer from user */
14 printf( "Enter an integer: " );
15 scanf( "%ld" , &number );
16
17 /* calculate fibonacci value for number input by user */
18 result = fibonacci( number );
19
20 /* display result */
21 printf( "Fibonacci( %ld ) = %ld\n" , number, result );
22
23 return ; /* indicates successful termination */
24
25 } /* end main */
26
Trang 4Program Output
Enter an integer: 0
Fibonacci( 0 ) = 0
Enter an integer: 1
Fibonacci( 1 ) = 1
Enter an integer: 2
Fibonacci( 2 ) = 1
Enter an integer: 3
Fibonacci( 3 ) = 2
Enter an integer: 4
Fibonacci( 4 ) = 3
31 if ( n == 0 || n == 1 ) {
32 return n;
33 } /* end if */
34 else { /* recursive step */
35 return fibonacci( n - 1 ) + fibonacci( n - 2 );
36 } /* end else */
37
38 } /* end function fibonacci */
13
Ví dụ 3 Đường Hilbert
quay theo 1 góc thích hợp và nối với nhau bởi 3 đoạn thẳng.
xác định bởi x, y
begin
if i > 0 then begin B(i−1); x := x − h; plot;
A(i−1); y := y − h; plot;
A(i−1); x := x + h; plot;
D(i−1);
end;
Trang 5 procedure B(i:integer);
procedure C(i:integer);
procedure D(i:integer);
Chương trình chính
Begin
read(n, x, y, h);
D(n);
end.
17
Ví dụ 4 Có n đĩa, kích thước khác nhau, có lỗ ở giữa
và ba cột kí hiệu là A, B, C Đĩa có thể xếp chồng lên
nhau, xuyên qua một cột để tạo thành hình tháp Giả
sử ban đầu n đĩa được đặt ở cột A theo thứ tự lớn dưới
nhỏ trên Cần dời các đĩa đến cột C nhưng vẫn phải
giữ thứ tự cũ, với các ràng buộc sau:
− Mỗi lần chỉ chuyển một đĩa từ cột này sang cột khác
− Đĩa lớn không được chồng lên đĩa nhỏ
− Được phép dùng cột B để làm trung gian
Trường hợp 1 đĩa: Chuyển đĩa từ cột A sang cột C
Trường hợp 2 đĩa:
từ cột A sang cột B
Trường hợp n đĩa (n >2)
Trang 6 Procedure HanoiTower(n, A, B, C: byte)
Begin
1 if n = 1 then Chuyển đĩa từ A sang C
2 else begin
Call HanoiTower(n−1, A, C, B);
Call HanoiTower(1, A, B, C);
Call HanoiTower(n − 1, B, A, C);
end;
21
Các thuật toán “ Chia để trị” (Divide−and−Conquer)
được bằng một thuật toán đơn giản Sau đó tổ hợp lời giải của
bộ dữ liệu S
THUẬT TOÁN QUAY LUI
Thuật ngữ: Backtracking [D.H Lehmer, 1950]
Cải tiến từ thuật toán tìm kiếm thô
Tìm kiếm có hệ thống, theo chiều sâu, trên tập các
phương án có thể
“Thử và sai” (“Trial-and-Error”)
Thường sử dụng đệ quy
Các ví dụ:
Thuật toán đệ quy
function Fac(i: integer): integer; {lưu ý nên dùng số nguyên lớn} begin
if i <=1 then Fac := 1 else Fac:= i * Fac(i − 1);
end;
Trang 7 Thuật toán không đệ quy (Sử dụng vòng lặp)
function Fac2(i: integer):integer;
begin
i := 0; F := 1;
while i < n do
begin
i := i +1;
F := F * i;
end;
end;
25
Đệ qui và lặp:
Lặp
Kết thúc
Cả hai đều có thể lặp vô hạn
Đệ quy là tốt nhất?
Khi nào nên dùng đệ quy
Những mô hình bài toán nên tránh dùng đệ quy:
P ≡ if B then S; P end;
hay P ≡ S; if B then P end;
BÀI TẬP
1 Xây dựng các hàm số sau bằng phương pháp đệ quy: f(x,n) = xn , (n >=0)
s(n) = (2n)!
2 Viết chương trình sử dụng hàm đệ quy để tính UCLN của hai số nguyên dương theo quy tắc sau:
• Nếu x= y thì UCLN(x, y) = x
• Nếu x > y thì UCLN(x, y) = UCLN(x − y, y);
• Nếu x < y thì UCLN(x, y) = UCLN(x, y −x);
Trang 83 Viết chương trình sử dụng hàm đệ quy để vẽ đường Hilber cấp k (k nhập vào từ bàn phím)
4 Viết chương trình sử dụng đệ quy để giải bài toán Tháp
Hà Nội