KỸ THUẬT LẬP TRÌNH (p7) pps

8 161 0
KỸ THUẬT LẬP TRÌNH (p7) pps

Đang tải... (xem toàn văn)

Thông tin tài liệu

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 returned 4! = 4 * 6 = 24 is re turne d 2! = 2 * 1 = 2 is returned 3! = 3 * 2 = 6 is retu 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 20 B B À À I TO I TO Á Á N TH N TH Á Á P H P H À À N N Ộ Ộ I I  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 B B À À I TO I TO Á Á N TH N TH Á Á P H P H À À N N Ộ Ộ I I  Các thuật toán “ Chia để trị” (Divide−and−Conquer) • Để giải bài toán B với bộ dữ liệu S, ta chia s thành các bộ dữ liệu con S 1 , S 2 , …, S k mà với bộ dữ liệu này, bài toán B giải được bằng một thuật toán đơn giản. Sau đótổ hợp lời giải của các bài toán trên bộ dữ liệu S i sẽ cho lời giải của bài toán B với bộ dữ liệu S. • Thường sử dụng lời gọi đệ quy 22 THU THU Ậ Ậ T TO T TO Á Á N QUAY LUI 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ụ: • Bài toán Quân Hậu • Bài toán Mã đi tuần • Bài toán Hôn nhân bền vững 23 KHI N KHI N À À O KHÔNG S O KHÔNG S Ử Ử D D Ụ Ụ NG Đ NG Đ Ệ Ệ QUY? QUY?  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; 24 KHI N KHI N À À O KHÔNG S O KHÔNG S Ử Ử D D Ụ Ụ NG Đ NG Đ Ệ Ệ QUY? QUY?  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 • Lặp: rõ ràng, kiểm soát trong quá trình chạy chương trình • Đệ qui: lặp lại lời gọi hàm  Kết thúc • Lặp: điều kiện lặp sai (false) • Đệ qui: nhận ra tình huống, điều kiện để kết thúc đệ qui  Cả hai đều có thể lặp vô hạn  Cân nhắc • Chọn giữa lặp và gọi đệ qui? 26 KHI N KHI N À À O KHÔNG S O KHÔNG S Ử Ử D D Ụ Ụ NG Đ NG Đ Ệ Ệ QUY? QUY?  Đệ 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; 27 B B À À I T I T Ậ Ậ P P 1. Xây dựng các hàm số sau bằng phương pháp đệ quy: f(x,n) = x n , (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); 28 B B À À I T I T Ậ Ậ P P 3. 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 . 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. . 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:. 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

Ngày đăng: 02/08/2014, 15:20

Tài liệu cùng người dùng

Tài liệu liên quan