Tải bản đầy đủ (.pdf) (8 trang)

Lập trình phát triển chương trình

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (237.77 KB, 8 trang )

0
K
K


THU
THU


T L
T L


P TRÌNH
P TRÌNH
KỸ THUẬT PHÁT TRIỂN CHƯƠNG TRÌNH
NỘI DUNG

Hàm và Thủ tục

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

Hàm đệ quy
1
KH
KH
Á
Á


I NI
I NI


M Đ
M Đ


QUY
QUY
?
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.
• Đệ quy trực tiếp: trong thủ tục P có chứa lời gọi đến chính nó
• Đệ quy gián tiếp: trong thủ tục P có lời gọi thủ tục Q và trong Q
có lời gọi đến P.
• Cần xác định tình huống, điều kiện để kết thúc đệ quy.
2

Ví dụ 1. Hàm tính giai thừa
• 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;
3

? 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ố;
}
4

Ví dụ 1. Hàm giai thừa
V
V
Í
Í
D
D


V
V



CHƯƠNG TRÌNH Đ
CHƯƠNG TRÌNH Đ


QUY
QUY



>−
=
=
0),1(*
0,1
)(
nifnFacn
nif
nFac
function Fac(i: integer): integer;
begin
if i <=1 then Fac := 1
else Fac:= i * Fac(i

1);
end;
5
5!
(a) Sequence of recursive calls. (b) Values returned from each recursive call.

Final va lue = 120
5! = 5 * 24 = 120 is re turned
4! = 4 * 6 = 24 is re turne d
2! = 2 * 1 = 2 is returne d
3! = 3 * 2 = 6 is re tu rn ed
1 returne d
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)
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 0; /* indicates successful termination */
19

20
} /* end main */
21



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 1;
28
} /* end if */
29
else { /* recursive step */
30
return ( number * factorial( number - 1 ) );

31
} /* end else */
32

33
} /* end function factorial */

8
V
V
Í
Í
D
D


V
V


CHƯƠNG TRÌNH Đ
CHƯƠNG TRÌNH Đ


QUY
QUY

Ví dụ 2. Dãy số Fibonacci

Bài toán:

• Các con thỏ không bao giờ chết.
• Hai tháng sau khi ra đời một cặp thỏ mới sẽ sinh ra một cặp
thỏ con (1 đực, 1 cái).
• Khi đã sinh con rồi thì cứ mỗi tháng tiếp theo chúng lại sinh
được một cặp mới.
• Giả sử bắt đầu từ một cặp mới ra đời thì đến tháng thứ n sẽ có
bao nhiêu cặp?
9
V
V
Í
Í
D
D


V
V


CHƯƠNG TRÌNH Đ
CHƯƠNG TRÌNH Đ


QUY
QUY

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
)(
nifnFibnFib
nif
nFib
10

Gọi function
fibonacci
f( 3 )
f( 1 )
f( 2 )
f( 1 ) f( 0 ) return 1
return 1 return 0
return
+

+
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 0; /* indicates successful termination */

24

25 } /* end main */
26


Program Output
Program 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
27 /* Recursive definition of function fibonacci */
28 long fibonacci( long n )
29 {
30 /* base case */
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
V
Í
Í
D
D


V
V


CHƯƠNG TRÌNH Đ
CHƯƠNG TRÌNH Đ


QUY
QUY

Ví dụ 3. Đường Hilbert
• Đường Hilbert cấp 0 là hình rỗng.
• Đường Hilbert cấp i + 1 được thành lập từ 4 đường cấp i được
quay theo 1 góc thích hợp và nối với nhau bởi 3 đoạn thẳng.
14
V
V

Í
Í
D
D


V
V


CHƯƠNG TRÌNH Đ
CHƯƠNG TRÌNH Đ


QUY
QUY
15
V
V
Í
Í
D
D


V
V


CHƯƠNG TRÌNH Đ

CHƯƠNG TRÌNH Đ


QUY
QUY

x, y - biến toạ độ; h - độ dài của đoạn nối; plot - vẽ từ vị trí hiện tại
xác định bởi x, y

procedure A(i:integer);
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;
16
V
V
Í
Í
D
D


V
V



CHƯƠNG TRÌNH Đ
CHƯƠNG TRÌNH Đ


QUY
QUY

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
V
Í
Í
D
D


V
V



CHƯƠNG TRÌNH Đ
CHƯƠNG TRÌNH Đ


QUY
QUY
18
B
B
À
À
I TO
I TO
Á
Á
N TH
N TH
Á
Á
P H
P H
À
À
N
N


I

I

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
19
B
B
À
À
I TO
I TO
Á
Á
N TH
N TH
Á
Á
P H
P H
À
À
N
N



I
I

Trường hợp 1 đĩa: Chuyển đĩa từ cột A sang cột C

Trường hợp 2 đĩa:
• Chuyển đĩa thứ nhất (tính từ đĩa trên cùng, hay đĩa nhỏ nhất)
từ cột A sang cột B
• Chuyển đĩa thứ 2 từ cột A sang cột C
• Chuyển đĩa thứ nhất từ cột B sang cột C.

Trường hợp n đĩa (n >2)
• Chuyển (n−1) đĩa từ cột A sang cột B
• Chuyển đĩa thứ n từ cột A sang cột C
• Chuyển (n − 1) đĩa từ cột B sang cột C

×