Giáo trình Kỹ thuật lập trình nâng cao
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Kỹ thuật lập trình nâng cao", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- giao_trinh_ky_thuat_lap_trinh_nang_cao.pdf
Nội dung text: Giáo trình Kỹ thuật lập trình nâng cao
- TRÖÔØNG ÑAÏI HOÏC ÑAØ LAÏT F 7 G GIAÙO TRÌNH KYÕ THUAÄT LAÄP TRÌNH NAÂNG CAO TRAÀN HOAØNG THOÏ 2002
- Kyõ thuaät laäp trình naâng cao - 2 - MUÏC LUÏC LÔØI NOÙI ÑAÀU 4 PHAÀN I 5 CHÖÔNG I 5 I. MÔÛ ÑAÀU 5 1. Moâ taû ñeä quy 5 2. Caùc loaïi ñeä quy 6 II. MOÂ TAÛ ÑEÄ QUY CAÙC CAÁU TRUÙC DÖÕ LIEÄU 7 III. MOÂ TAÛ ÑEÄ QUY GIAÛI THUAÄT 7 1. Giaûi thuaät ñeä quy 7 2. Chöông trình con ñeä quy 8 3. Maõ hoùa giaûi thuaät ñeä qui trong caùc ngoân ngöõ laäp trình. 11 4. Moät soá daïng giaûi thuaät ñeä quy ñôn giaûn thöôøng gaëp . 13 CHÖÔNG II 16 I. CAÙC NOÄI DUNG CAÀN LAØM ÑEÅ TÌM GIAÛI THUAÄT ÑEÄ QUY CHO MOÄT BAØI TOAÙN. 16 1. Thoâng soá hoaù baøi toaùn. 16 2. Phaùt hieän caùc tröôøng hôïp suy bieán (neo) vaø tìm giaûi thuaät cho caùc tröôøng hôïp naøy.16 3. Phaân raõ baøi toaùn toång quaùt theo phöông thöùc ñeä quy. 16 II. MOÄT SOÁ BAØI TOAÙN GIAÛI BAÈNG GIAÛI THUAÄT ÑEÄ QUY ÑIEÅN HÌNH. 17 1. Baøi toaùn thaùp Haø Noäi . 17 2. Baøi toaùn chia thöôûng. 19 3. Baøi toaùn tìm taát caû caùc hoaùn vò cuûa moät daõy phaàn töû 21 4. Baøi toaùn saép xeáp maûng baèng phöông phaùp troän (Sort-Merge). 24 5. Baøi toaùn tìm nghieäm xaáp xæ cuûa phöông trình f(x)=0 . 25 CHÖÔNG III 28 I. CÔ CHEÁ THÖÏC HIEÄN GIAÛI THUAÄT ÑEÄ QUY 28 II. TOÅNG QUAN VEÀ VAÁN ÑEÀ KHÖÛû ÑEÄ QUY 32 III. CAÙC TRÖÔØNG HÔÏP KHÖÛ ÑEÄ QUY ÑÔN GIAÛN. 33 1. Caùc tröôøng hôïp khöû ñeä quy baèng voøng laëp . 33 2. Khöû ñeä quy haøm ñeä quy arsac 41 3. Khöû ñeä quy moät soá daïng thuû tuïc ñeä quy thöôøng gaëp. 45 Phaàn II 52 CHÖÔNG IV 52 I. CAÙC GIAI ÑOAÏN TRONG CUOÄC SOÁNG CUÛA MOÄT PHAÀN MEÀM 52 1) Ñaëc taû baøi toaùn 52 2) Xaây döïng heä thoáng 52 3) Söû duïng vaø baûo trì heä thoáng 53 II. ÑAËC TAÛ 53 1. Ñaëc taû baøi toaùn 53 2. Ñaëc taû chöông trình (ÑTCT) 54 3. Ñaëc taû ñoaïn chöông trình 55 III. NGOÂN NGÖÕ LAÄP TRÌNH 57 CHÖÔNG V 59 I. CAÙC KHAÙI NIEÄM VEÀ TÍNH ÑUÙNG. 59 II. HEÄ LUAÄT HOARE (HOARES INFERENCE RULES). 59 1. Caùc luaät heä quaû (Consequence rules) 60 Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 3 - 2. Tieân ñeà gaùn (The Assignement Axiom) 61 3. Caùc luaät veà caùc caáu truùc ñieàu khieån . 61 III. KIEÅM CHÖÙNG ÑOAÏN CHÖÔNG TRÌNH KHOÂNG COÙ VOØNG LAËP. 64 IV. KIEÅM CHÖÙNG ÑOAÏN CHÖÔNG TRÌNH COÙ VOØNG LAËP. 68 1. Baát bieán 68 2. Lyù luaän quy naïp vaø chöùng minh baèng quy naïp 70 3. Kieåm chöùng chöông trình coù voøng laëp while. 71 CHÖÔNG VI 76 I. CAÙC KHAÙI NIEÄM. 76 1. Ñaët vaán ñeà. 76 2. Ñònh nghóa WP(S,Q) 76 3. Heä quaû cuûa ñònh nghóa 76 4. Caùc ví duï 77 II. TÍNH CHAÁT CUÛA WP 77 III. CAÙC PHEÙP BIEÁN ÑOÅI TAÂN TÖØ 78 1. Toaùn töû gaùn (tieân ñeà gaùn). 78 2. Toaùn töû tuaàn töï 78 3. Toaùn töû ñieàu kieän. 79 4. Toaùn töû laëp 80 IV. LÖÔÏC ÑOÀ KIEÅM CHÖÙNG HÔÏP LYÙ VAØ CAÙC ÑIEÀU KIEÄN CAÀN KIEÅM CHÖÙNG 84 1. Löôïc ñoà kieåm chöùng. 84 2. Kieåm chöùng tính ñuùng 85 3. Taäp toái tieåu caùc ñieàu kieän caàn kieåm chöùng. 93 PHU LUÏC 96 I. LOGIC TOAÙN 96 II. LOGIC MEÄNH ÑEÀ 96 1. Phaân tích 96 2. Caùc lieân töø logic. 97 3. YÙnghóa cuûa caùc lieân töø Logic. Baûng chaân trò. 97 4. Lyù luaän ñuùng. 98 5. Töông ñöông (Equivalence) 99 6. Tính thay theá, tính truyeàn vaø tính ñoái xöùng 100 7. Baøi toaùn suy dieãn logic 100 8. Caùc luaät suy dieãn (rules of inference). 102 III. LOGIC TAÂN TÖØ. 103 1. Khaùi nieäm 103 2. Caùc löôïng töø logic 105 3. Taäp hôïp vaø taân töØ 107 4. Caùc löôïng töø soá hoïc 107 Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 4 - LÔØI NOÙI ÑAÀU Giaùo trình ñöôïc vieát theo noäi dung moân hoïc “ Kyõ thuaät laäp trình naâng cao” vôùi muïc ñích laøm taøi lieäu tham khaûo chính cho moân hoïc. Giaùo trình goàm 2 phaàn chính vaø moät phuï luïc : Phaàn I. Ñeä quy. Trình baøy veà chuû ñeà ñeä quy trong laäp trình bao goàm caùc noäi dung sau : - Khaùi nieäm ñeä quy vaø vai troø cuûa noù trong laäp trình. - Caùch xaây döïng moät giaûi thuaät cho moät baøi toaùn baèng phöông phaùp ñeä quy. - Cô cheá thöïc hieän moät giaûi thuaät ñeä quy. - Khöû ñeä quy. Phaàn II. Kieåm chöùng chöông trình. Trình baøy veà chuû ñeà kieåm chöùng tính ñuùng cuûa chöông trình bao goàm caùc noäi dung sau: - Vai troø cuûa vaán ñeà kieåm chöùng trong laäp trình. - Caùc phöông phaùp duøng ñeå kieåm chöùng tính ñuùng . - Heä luaät Hoare vaø aùp duïng cuûa noù vaøo kieåm chöùng tính ñuùng coù ñieàu kieän. - Heä luaät Dijkstra vaø aùp duïng cuûa noù vaøo kieåm chöùng tính ñuùng ñaày ñuû. - Daïng toång quaùt cuûa baøi toaùn kieåm chöùng vaø phöông phaùp kieåm chöùng. Caùc löôïc ñoà kieåm chöùng vaø taäp toái thieåu caùc ñieàu kieän caàn kieåm chöùng. Phuï luïc . Caùc kieán thöùc chung veà logic. Trình baøy caùc kieán thöùc ban ñaàu veà logic meänh ñeà vaø logic taân töø. Phuï luïc cung caáp moät moät taøi lieäu coâ ñoïng veà caùc kieán thöùc logic aùp duïng tröïc tieáp trong phaàn I vaø phaàn II ( noù laø moät phaàn noâi dung cuûa giaùo trình nhaäp moân toaùn) ngöôøi hoïc caàn daønh thôøi gian thích hôïp oân laïi ñeå coù theå theo kòp höôùng tieáp caän cuûa giaùo trình. Cuøng vôùi nhöõng trình baøy lyù thuyeát toång quaùt, taùc gæa ñöa vaøo moät soá thoûa ñaùng caùc ví duï choïn loïc nhaèm giuùp ngöôøi hoïc naém baét ñöôïc baûn chaát cuûa caùc khaùi nieäm, caùc phöông phaùp môùi vaø laøm quen vôùi caùch söû duïng caùc keát quûa môùi. Khi hoïc tröôùc khi tìm caùch giaûi caùc baøi taäp cuûa thaày gíao cung caáp caùc baïn coá gaéng ñoïc vaø hieåu heát caùc ví duï minh hoïa. Vì nhieàu leõ chaéc chaén giaùo trình coøn nhieàu khieám khuyeát. Raát mong taát caû moïi ngöôøi söû duïng chaân thaønh goùp yù. Taùc giaû chaân thaønh caûm ôn caùc ñoàng nghieäp trong khoa Toaùn_Tin ñaõ ñoùng goùp nhieàu yù kieán quyù baùu cho vieäc hình thaønh caáu truùc chi tieát cho noäi dung giaùo trình, chaân thaønh caûm ôn thaïc syõ Voõ Tieán ñaõ ñoùng goùp nhieàu yù kieán quyù baùu trong caáu truùc giaùo trình, giuùp chænh lyù nhieàu khieám khuyeát trong baûn thaûo. ÑaLat ngaøy 01 thaùng 12 naêm 2002 TRAÀN HOAØNG THOÏ Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 5 - PHAÀN I ÑEÄ QUY CHÖÔNG I KHAÙI NIEÄM ÑEÄ QUY I. MÔÛ ÑAÀU 1. Moâ taû ñeä quy Trong nhieàu tình huoáng vieäc moâ taû caùc baøi toaùn, caùc giaûi thuaät, caùc söï kieän, caùc söï vaät caùc quaù trình, caùc caáu truùc, . . . seõ ñôn giaûn vaø hieäu quaû hôn neáu ta nhìn ñöôïc noù döôùi goùc ñoä mang tính ñeä qui. Moâ taû mang tính ñeä qui veà moät ñoái töôïng laø moâ taû theo caùch phaân tích ñoái töôïng thaønh nhieàu thaønh phaàn maø trong soá caùc thaønh phaàn coù thaønh phaàn mang tính chaát cuûa chính ñoái töôïng ñöôïc moâ taû. Töùc laø moâ taû ñoái töôïng qua chính noù. Caùc ví duï : - Moâ taû ñeä quy taäp soá töï nhieân N : + Soá 1 laø soá töï nhieân ( 1 ∈ N) . + Soá töï nhieân baèng soá töï nhieân coäng 1 . ( n ∈ N ⇒ ( n +1 ) ∈ N ) - Moâ taû ñeä quy caáu truùc xaâu (list) kieåu T : + Caáu truùc roãng laø moät xaâu kieåu T. + Gheùp noái moät thaønh phaàn kieåu T(nuùt kieåu T ) vôùi moät xaâu kieåu T ta coù moät xaâu kieåu T. - Moâ taû ñeä quy caây gia phaû : Gia phaû cuûa moät ngöôøi bao goàm mgöôøi ñoù vaø gia phaû cuûa cha vaø gia phaû cuûa meï. - Moâ taû ñeâ quy thuû tuïc choïn hoa haäu : + Choïn hoa haäu cuûa töøng khu vöïc. + Choïn hoa haäu cuûa caùc hoa haäu. - Moâ taû ñeä quy thuû tuïc saép taêng daõy a[m:n] ( daõy a[m], a[m+1], . . . , a[n] ) baèng phöông phaùp Sort_Merge (SM) : SM (a[m:n]) ≡ Merge ( SM(a[m : (n+m) div 2]) , SM (a[(n+m) div 2 +1 : n] ) Vôùi : SM (a[x : x]) laø thao taùc roãng (khoâng laøm gì caû ). Merge (a[x : y] , a[(y+1) : z]) laø thuû tuïc troän 2 daõy taêng a [x : y] , a[(y+1) : z] ñeå ñöôïc moät daõy a[x : z] taêng. - Ñinh nghóa ñeä quy haøm giai thöøa FAC( n) = n ! 0 ! = 1 n ! = n * ( n - 1 ) ! Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 6 - Phöông phaùp ñeä quy maïnh ôû choå noù cho pheùp moâ taû moät taäp lôùn caùc ñoái töôïng chæ bôûi moät soá ít caùc meänh ñeà hoaëc moâ taû moät giaûi thuaät phöùc taïp baèng moät soá ít caùc thao taùc (moät chöông trình con ñeä quy). Moät moâ taû ñeä quy ñaày ñuû goàm 2 phaàn : - Phaàn neo : moâ taû caùc tröôøng hôïp suy bieán cuûa ñoái töôïng (giaûi thuaät) qua moät caáu truùc (thao taùc) cuï theå xaùc ñònh . ví duï: 1 laø soá töï nhieân, caáu truùc roãng laø moät xaâu kieåu T, 0 ! = 1 , SM (a[x:x]) laø thao taùc roãng. - Phaàn quy naïp: moâ taû ñoái töôïng (giaûi thuaät) trong tröôøng hôïp phoå bieán thoâng qua chính ñoái töôïng (giaûi thuaät ) ñoù moät caùch tröïc tieáp hoaëc giaùn tieáp. Ví duï : n! = n * (n – 1) ! SM (a[m:n]) ≡ Merge (SM (a[m:( m+n) div 2] , SM (a[(m+n) div 2 +1 : n]) ) Neáu trong moâ taû khoâng coù phaàn neo thì ñoái töôïng moâ taû coù caáu truùc lôùn voâ haïn, giaûi thuaät moâ taû trôû thaønh caáu truùc laëp voâ taän. 2. Caùc loaïi ñeä quy Ngöôøi ta phaân ñeä quy thaønh 2 loaïi : Ñeä quy tröïc tieáp, ñeä quy giaùn tieáp. - Ñeä quy tröïc tieáp laø loaïi ñeä quy maø ñoái töôïng ñöôïc moâ taû tröïc tieáp qua noù : A moâ taû qua A, B, C, trong ñoù B, C, khoâng chöùa A. (caùc ví duï treân). - Ñeä quy giaùn tieáp laø loaïi ñeä quy maø ñoái töôïng ñöôïc moâ taû giaùn tieáp qua noù : A moâ taû qua A1 ,A2 , , An .Trong ñoù coù moät Ai ñöôïc moâ taû qua A. Ví duï 1: Moâ taû daïng toång quaùt moät chöông trình vieát treân NNLT Pascal : Moät Chöông trình Pascal goàm : a) Ñaàu chöông trình (head) goàm: Program Teân ; b) Thaân chöông trình (blok) goàm : b1) Khai baùo unit, ñònh nghóa haèng, nhaõn, kieåu döõ lieäu, khaùi baùo bieán. b2) Ñònh nghóa caùc chöông trình con goàm : b2.1) Ñaàu chöông trình con : Procedure Teân thuû tuïc ( danh saùch thoâng soá hình thöùc ) ; hoaëc Function Teân haøm ( danh saùch thoâng soá hình thöùc ) : Kieåu ; b2.2) Thaân chöông trình con ( Blok ) b2.3) Daáu ‘ ; ‘ b3) Phaàn leänh : laø moät leänh gheùp daïng : Begin S1 ; S2 ; . . . ; Sn End ; c) Daáu keát thuùc chöông trình : ‘.’ Ví duï 2 : Moâ taû hai daõy soá {Xn},{Yn} theo luaät ñeä quy hoå töông nhö sau : X0 = 1 ; Xn = Xn-1 + Yn-1 ; 2 Y0 = 1 ; Yn =n Xn-1 + Yn-1 ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 7 - II. MOÂ TAÛ ÑEÄ QUY CAÙC CAÁU TRUÙC DÖÕ LIEÄU Trong toaùn hoïc , trong laäp trình ngöôøi ta thöôøng söû duïng ñeä quy ñeå moâ taû caùc caáu truùc phöùc taïp, coù tính ñeä quy . Bôûi moâ taû ñeä quy khoâng chæ laø caùch moâ taû ngaén goïn caùc caáu truùc phöùc taïp maø coøn taïo khaû naêng ñeå xaây döïng caùc thao taùc xöû lyù treân caùc caáu truùc phöùc taïp baèng caùc giaûi thuaät ñeä qui . Moät caáu truùc döõ lieäu coù tính ñeä quy thöôøng goàm moät soá thaønh phaàn döõ lieäu cuøng kieåu ñöôïc gheùp noái theo cuøng moät phöông thöùc . Ví duï 1: Moâ taû ñeä quy caây nhi phaân : Caây nhi phaân kieåu T : + Hoaëc laø moät caáu truùc roãng (phaàn neo). + Hoaëc laø moät nuùt kieåu T (nuùt goác) vaø 2 caây nhò phaân kieåu T rôøi nhau (caây con nhò phaân phaûi, caây con nhò phaân traùi) keát hôïp vôùi nhau . Ví duï 2: Moâ taû ñeä quy maûng nhieàu chieàu : + Maûng moät chieàu laø daõy coù thöù töï caùc thaønh phaàn cuøng kieåu . + Maûng n chieàu laø maûng 1 chieàu maø caùc thaønh phaàn coù kieåu maûng n-1 chieàu . III. MOÂ TAÛ ÑEÄ QUY GIAÛI THUAÄT 1. Giaûi thuaät ñeä quy. Giaûi thuaät ñeä quy laø giaûi thuaät coù chöùa thao taùc goïi ñeán noù . Giaûi thuaät ñeä quy cho pheùp moâ taû moät daõy lôùn caùc thao taùc baèng moät soá ít caùc thao taùc trong ñoù coù chöùa thao taùc goïi laïi giaûi thuaät (goïi ñeä quy) . Moät caùch toång quaùt moät giaûi thuaät ñeä quy ñöôïc bieåu dieãn nhö moät boä P goàm meänh ñeà S (khoâng chöùa yeáu toá ñeä quy ) vaø P : P ≡ P[ S , P ] . Thöïc thi giaûi thuaät ñeä quy coù theå daãn tôùi moät tieán trình goïi ñeâ quy khoâng keát thuùc khi noù khoâng coù khaû naêng gaëp tröôøng hôïp neo, vì vaäy quan taâm ñeán ñieàu kieän döøng cuûa moät giaûi thuaät ñeä quy luoân ñöôïc ñaët ra . Ñeå kieåm soaùt quùa trình goïi ñeä quy cuûa giaûi thuaät ñeä quy P ngöôøi ta thöôøng gaén thao taùc goïi P vôùi vieäc kieåm tra moät ñieàu kieän B xaùc ñònh vaø bieán ñoåi qua moãi laàn goïi P , quùa trình goïi P seû döøng khi B khoâng con thoûa. Moâ hình toång quaùt cuûa moät giaûi thuaät ñeä quy vôùi söï quan taâm ñeán söï döøng seû laø : P ≡ if B then P[ S , P ] hoaëc P ≡ P[ S , if B then P ] Thoâng thöôøng vôùi giaûi thuaät ñeä quy P , ñeå ñaûm baûo P seû döøng sau n laàn goïi ta choïn B laø ( n >0 ) . Moâ hình giaûi thuaät ñeä quy khi ñoù coù daïng : P(n) ≡ If ( n > 0 ) then P[ S , P(n - 1)] ; hoaëc P(n) ≡ P[ S , if (n >0) then P(n - 1) ] ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 8 - Trong caùc öùng duïng thöïc teá soá laàn goïi ñeä quy (ñoä saâu ñeä quy) khoâng nhöõng phaûi höõu haïn maø coøn phaûi ñuû nhoû . Bôûi vì moãi laàn goïi ñeä quy seõ caàn moät vuøng nhôù môùi trong khi vuøng nhôù cuõ vaãn phaûi duy trì . 2. Chöông trình con ñeä quy. a) Caùc haøm ñeä quy. Ñònh nghóa haøm soá baèng ñeä quy thöôøng gaëp trong toaùn hoïc, ñieån hình laø caùc haøm nguyeân moâ taû caùc daõy soá hoài quy . Ví duï 1 . Daõy caùc giai thöøa : { n! } ≡ 1 ,1 , 2 , 6 , 24 , 120 , 720 , 5040 , . . . Kyù hieäu FAC(n ) = n ! . Ta coù : + FAC(0 ) = 1 ; ( 0 ! = 1 ) + FAC(n ) = n * FAC(n - 1 ) ; ( n ! = n * (n - 1 ) ! ) vôùi n >= 1 Giaûi thuaät ñeä quy tính FAC(n ) laø : FAC(n ) ≡ if (n = 0 ) then return 1 ; else return (n * FAC(n - 1 )) ; Ví duï 2 . Daõy soá Fibonaci(FIBO) : { FIBO (n) } ≡ 1 ,1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 , 89 , 144 , 233 , 377 , . . . + FIBO(0 ) = FIBO (1 ) = 1 ; + FIBO(n ) = FIBO (n - 1 ) + FIBO ( n - 2 ) ; vôùi n > = 2 Giaûi thuaät ñeä quy tính FIBO ( n ) laø : FIBO(n) ≡ if ((n = 0 ) or ( n = 1 )) then return 1 ; else return ( FIBO (n - 1) + FIBO (n - 2)) ; Ví duï 3 . Daõy caùc toå hôïp : 1 1 2 1 1 3 3 1 1 4 6 4 1 0 Cn = 1 vôùi n > = 0 m Cn = 0 vôùi m > n > 0 m m−1 m CCn =n−1 +Cn−1 vôùi n > m > 0 m Giaûi thuaät ñeä quy tính Cn laø : if ( m = 0 ) then return 1 ; else if (m > n ) then return 0 ; m−1 m else return ( Cn−1 + Cn−1 ) ; Nhaän xeùt : Moät ñònh nghóa haøm ñeä quy goàm : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 9 - + Moät soá caùc tröôøng hôïp suy bieán maø gía trò haøm taïi ñoù ñaõ ñöôïc bieát tröôùc hoaëc coù theå tính moät caùch ñôn giaûn (khoâng ñeä quy ) . Nhö : 0 m FAC(0 ) = 1 , FIBO(0) = FIBO(1) = 1 , Cn = 1 , Cn = 0 vôùi m > n > 0 . + Tröôøng hôïp toång quaùt vieäc tính haøm seû ñöôc ñöa veà tính haøm ôû giaù trò “ beù hôn” (gaàn vôùi giaù trò neo) cuûa ñoái soá . Nhö : FAC(n ) = n * FAC(n - 1 ) ; FIBO(n) = FIBO(n -1) + FIBO( n - 2 ) . Trong taäp bieán cuûa haøm coù moät nhoùm maø ñoä lôùn cuûa noù quyeát ñònh ñoä phöùc taïp cuûa vieäc tính gía trò haøm . Nhoùm bieán ñoù goïi laø nhoùm bieán ñieàu khieån . Gía trò bieân cuûa nhoùm bieán ñieàu khieån öùng vôùi tröôøng hôïp suy bieán . Gía trò cuûa nhoùm bieán ñieàu khieån seû thay ñoåi qua moãi laàn goïi ñeä quy vôùi xu höôùng tieán ñeán gía trò bieân ( töông öùng vôùi caùc tröôøng hôïp suy bieán cuûa haøm ). b) Caùc thuû tuïc ñeä quy. Thuû tuïc ñeä quy laø thuû tuïc coù chöùa leänh goïi ñeán noù . Thuû tuïc ñeä quy thöôøng ñöôïc söû duïng ñeå moâ taû caùc thao taùc treân caáu truùc döõ lieäu coù tính ñeä quy Ví duï 1 : Xem daõy n phaàn töû a[1:n] laø söï keát hôïp giöõa daõy a[1:n-1] vaø a[n] . Do ño ù: - Thuû tuïc tìm max trong daõy a[1:n] ( thuû tuïc TMax) coù theå thöïc hieän theo luaät ñeä qui : + Tìm max trong daõy con a[1:n] (goïi ñeä quy Tmax(a[1:n-1] ) ). + Tìm max cuûa 2 soá : Tmax(a[1:n-1]) vaø a[n] (giaûi thuaät khoâng ñeä quy). Töùc laø : TMax(a[1:n]) = max(TMax(a[1:n-l]) , a[n] ) vôùi TMax(a[m:m] = a[m] ; ( tröôøng hôïp neo ) max(x,y) = x > y ? x : y ; ( giaûi thuaät tính max 2 soá : if (x>y) then max(x ,y) = x else max(x ,y) = y ) - Thuû tuïc tính toång caùc phaàn töû ( thuû tuïc TSUM ) coù theå thöïc hieän theo luaät ñeä quy : + Tìm toång daõy con a[1:n] (goïi ñeä quy TSUM(a[1:n-1]) ). + Tìm toång cuûa 2 soá : TSUM(a[1:n-1]) vaø a[n] (giaûi thuaät khoâng ñeä quy). Töùc laø : TSUM(a[1:n]) = a[n] + TSUM(a[1:n-1] vôùi TSUM(a[m:m]) = a[m] Ví duï 2 : Xem daõy a[m : n] laø söï keát noái giöõa hai daõy: daõy a[m:((m+n) div 2)] vaø daõy a[(((m+n) div 2)+1) :n] . Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 10 - Do ño ù: - Thuû tuïc tìm max trong daõy a[1:n] ( thuû tuïc Tmax1) coù theå thöïc hieän theo luaät ñeä qui : + Tìm max trong daõy con traùi a[m:((m+n) div 2)] (goïi ñeä quy Tmax1(a[m:((m+n) div 2)] ) ). + Tìm max trong daõy con phaûi a[(((m+n) div 2)+1) :n] . (goïi ñeä quy Tmax1(a[(((m+n) div 2)+1) :n] ). + Tìm max cuûa 2 soá : Tmax1(a[m:((m+n) div 2)] ) vaø Tmax1(a[(((m+n) div 2)+1) :n] ). (giaûi thuaät khoâng ñeä quy). Töùc laø :Tmax1(a[m:n]) = max(Tmax1(a[m:((m+n) div 2)] ) ,Tmax1(a[(((m+n) div 2)+1) :n]) ). vôùi Tmax1(a[m:m] = a[m] ; ( tröôøng hôïp neo ) max(x,y) = x > y ? x : y ; - Thuû tuïc tính toång caùc phaàn töû ( TSUM1 ) coù theå thöïc hieän theo luaät ñeä quy : + Tìm toång daõy con traùi a[m:((m+n) div 2)] (goïi ñeä quy TSUM1 (a[m:((m+n) div 2)] ) ). + Tìm toång daõy con phaûi a[(((m+n) div 2)+1) :n] . (goïi ñeä quy TSUM1 (a[(((m+n) div 2)+1) :n] ) ). + Tìm toång cuûa 2 soá : TSUM1 (a[m:((m+n) div 2)] ) vaø TSUM1 (a[(((m+n) div 2)+1) :n] ). Töùc laø : TSUM1 (a[m:n]) = TSUM1 (a[m:((m+n) div 2)]) + TSUM1 (a[(((m+n) div 2)+1) :n] ) vôùi TSUM1 (a[m:m]) = a[m] Ví duï 3 : Caây nhò phaân tìm kieám kieåu T(BST) laø moät caáu truùc goàm : moät nuùt kieåu T keát noái vôùi 2 caây con nhi phaân tìm kieám kieåu T neân : - Thuï tuïc queùt caây nhi nhaân tìm kieám theo thöù töï giöõa (LNF) laø : + Queùt caây con traùi theo thöù töï giöõa ; + Thaêm nuùt goác ; + Queùt caây con phaûi theo thöù töï giöõa ; - Thuû tuïc tìm kieám giaù tri αo treân caây nhò phaân tìm kieám Root laø : Neáu Root ≡ ∅ thì thöïc hieän thao taùc roãng (khoâng laøm gì ) Con khoâng neáu giaù trò taïi nuùt goác = αo thì thoâng baùo tìm thaáy vaø döøng Coøn khoâng neáu giaù trò taïi nuùt goác < αo thì tìm ôû caây con traùi Coøn khoâng thì tìm ôû caây con phaûi . Nhaän xeùt : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 11 - Trong moät thuû tuïc ñeä qui, ñeå cho vieäc goïi ñeä quy döøng laïi sau höõu haïn laàn goïi noù caàn chöùa ñieàu kieän kieåm tra (moät bieåu thöùc boolean B treân moät nhoùm bieán ) , ñeå khi ñieàu kieän naøy khoâng coøn thoûa thì vieäc goïi ñeä qui keát thuùc . Daïng thöôøng gaëp cuûa thuû tuïc ñeä qui laø : S1 ; ( khoâng chöùa yeáu toá ñeä qui ) if B then S2 ( phaàn leänh tröïc tieáp , khoâng coù leänh goïi ñeä qui ) else Sdq ; ( phaàn leänh coù leänh goïi ñeä qui ) S3 ; (khoâng coù goïi ñeä qui ) 3. Maõ hoùa giaûi thuaät ñeä qui trong caùc ngoân ngöõ laäp trình. a) Toång quan. Khoâng phaûi moïi ngoân ngöõ laäp trình hieän coù ñeàu coù theå maõ hoùa ñöôïc giaûi thuaät ñeä quy, chæ moät soá nhöõng ngoân ngöõ laäp trình coù khaû naêng toå chöùc vuøng nhôù kieåu stack môùi coù khaû naêng maõ hoùa ñöôïc giaûi thuaät ñeä quy . Caùc ngoân ngöõ laäp trình hieän nay ñeàu maõ hoùa giaûi thuaät ñeä quy baèng caùch toå chöùc caùc chöông trình con ñeä quy töông öùng . b) Theå hieän ñeä qui trong NNLT PASCAL vaø C++ NN LT Pascal vaø C++ ñeàu cho pheùp maõ hoùa giaûi thuaät ñeä quy baèng caùch toå chöùc chöông trình con ñeâ quy nhôø vaøo cô cheá taïo vuøng nhôù Stak cuûa phaàn meàm ngoân ngöõ . b1) Trong NNLT C++. NNLT C++ cho pheùp maõ hoùa giaûi thuaät ñeä quy moät caùch thuaän lôïi nhôø vaøo kyõ thuaät khai baùo tröôùc tieâu ñeà neân khoâng coù söï phaân bieät hình thöùc naøo trong vieäc khai baùo giöõa haøm con ñeä quy vaø haøm con khoâng ñeä quy. b2) Trong NN LT Pascal . Ñoái vôùi chöông trình con ñeä quy tröïc tieáp thì hình thöùc khai baùo cuõng gioáng nhö ñoái vôùi chöông trình con khoâng ñeä quy. Ñoái vôùi chöông trình con ñeä quy giaùn tieáp thì hình thöùc khai baùo coù thay ñoåi ít nhieàu nhaèm thoûa quy taéc taàm vöïc cuûa ngoân ngöõ ( trong phaàn leänh cuûa moät chöông trình con chæ ñöôïc goïi nhöõng chöông trình con cuøng caáp ñaõ ñöôïc khai baùo tröôùc ). Ví duï : Vôùi moâ hình chöông trình sau : Trong phaàn leänh cuûa khoái A coù theå goïi ñeán : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 12 - Program + Goïi caùc chöông trình con tröïc tieáp cuûa noù E goïi ñöôïc B nhöng khoâng goïi ñöôïc C + Goïi chính noù ( goïi ñeä quy ). + Goïi chöông trình con cuøng caáp nhömg A phaûi khai baùo tröôùc goïi ñöôïc E nhöng B khoâng goïi ñöôïc D , Muoán goïi D phaûi C khai baùo tröôùc ( khai baùo FORWARD) D Khai baùo tröôùc FORWARD . Ñeå töø thuû tuïc haøm A coù theå goïi ñeán D laø thuû tuïc haøm cuøng caáp nhöng ñöôïc moâ taû sau A, ta caàn coù moät khai baùo tröôùc cuûa D ôû phía tröôùc cuûa A . Khai baùo naøy goàm : tieâu ñeà cuûa D, vôùi danh saùch thoâng soá cuûa D, tieáp theo laø töø khoaù FORWARD . Sau ñoù luùc moâ taû laïi D thì chæ caàn khai baùo töø khoaù PROCEDURE ( hoaëc FUNCTION ) , teân cuûa D ( khoâng coù danh saùch thoâng soá ) , phaàn thaân cuûa D. Ví duï : Vôùi 2 thuû tuïc goïi ñeä quy hoã töông nhau FIRST,SECOND seõ ñöôïc khai baùo nhö sau : procedure SECOND (i : integer ) ; Forward ; procedure FIRST (n : integer ; var X : real); var j, k : interger ; begin for j := 1 to n do begin writeln(‘ j = ‘, j ) ; k := n – 2* j ; SECOND( k ); end ; end ; procedure second ; begin if ( i > 0 ) then begin writeln(‘ i= ‘, i ); FIRST( i – 1 ) ; end ; end ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 13 - 4. Moät soá daïng giaûi thuaät ñeä quy ñôn giaûn thöôøng gaëp . a) Ñeä quy tuyeán tính. Chöông trình con ñeä quy tuyeán tính laø chöông trình con ñeä quy tröïc tieáp ñôn giaûn nhaát coù daïng : P ≡ { NEÁU thoûa ñieàu kieän döøng thì thöïc hieän S ; Coøn khoâng begin { thöïc hieän S* ; goïi P } } Vôùi S , S* laø caùc thao taùc khoâng ñeä quy . Ví duï 1 : Haøm FAC(n) tính soá haïng n cuûa daõy n! + Daïng haøm trong ngoân ngöõ maõ giaû : { Neáu n = 0 thì FAC = 1 ; /* tröôøng hôïp neo */ Coøn khoâng FAC = n*FAC(n-1) } + Daïng haøm trong ngoân ngöõ Pascal : Function FAC(n : integer) : integer; begin if( n = 0 ) then FAC := 1 else FAC := n*FAC(n-1) ; end; + Daïng haøm trong C++ : int FAC( int n ) { if ( n == 0 ) return 1 ; else return ( n * FAC(n-1 )) ; } Ví duï 2 : Chöông trình con tính USCLN cuûa 2 soá döïa vaøo thuaät toaùn Euclide : + Daïng haøm treân ngoân ngöõ toaùn hoïc : USCLN(m , n ) = USCLN(n , m mod n ) khi n ≠ 0 USCLN(m , 0) = m + Daïng haøm trong ngoân ngöõ maõ giaû : Neáu n = 0 thì USCLN = m Coøn khoâng USCLN = USCLN( n , m mod n ) ; + Daïng haøm trong Pascal : Function USCLN(m , n : integer ) : integer ; begin if (n = 0 ) then USCLN := m else USCLN := USCLN( n , m mod n ) ; end ; +Daïng haøm trong C++ : int USCLN( int m , int n ) Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 14 - { if(n == 0 ) return (m) ; else return ( USCLN( n , m mod n)) ; } b) Ñeä quy nhò phaân. Chöông trình con ñeä quy nhò phaân laø chöông trình con ñeä quy tröïc tieáp coù daïng : P ≡ { NEÁU thoûa ñieàu kieän döøng thì thöïc hieän S ; Coøn khoâng begin { thöïc hieän S* ; goïi P ; goïi P } } Vôùi S , S* laø caùc thao taùc khoâng ñeä quy . Ví duï 1 : Haøm FIBO(n) tính soá haïng n cuûa daõy FIBONACCI + Daïng haøm trong Pascal: Function F(n : integer) : integer; begin if( n < 2 ) then F := 1 else F := F(n-1) + F(n-2) end; + Daïng haøm trong C++ : int F(int n) { if ( n < 2 ) return 1 ; else return (F(n -1) + F(n -2)) ; } c) Ñeä quy phi tuyeán. Chöông trình con ñeä quy phi tuyeán laø chöông trình con ñeä quy tröïc tieáp maø lôøi goïi ñeä quy ñöôïc thöïc hieän beân trong voøng laëp . Daïng toång quaùt cuûa chöông trình con ñeä quy phi tuyeán laø : P ≡ { for giaù tri ñaàu to giaù trò cuoái do begin thöïc hieän S ; if ( thoûa ñieàu kieän döøng ) then thöïc hieän S* else goïi P end ; } Vôùi S , S* laø caùc thao taùc khoâng ñeä quy . Ví duï : Cho daõy { Xn } xaùc ñònh theo coâng thöùc truy hoài : 2 2 2 2 X0 = 1 ; Xn = n XO +(n-1) X1 + . . . + 2 Xn-2 + 1 Xn-1 + Daïng haøm ñeä quy tính Xn treân ngoân ngöõ maõ giaû laø : Xn ≡ if ( n= 0 ) then return 1 ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 15 - else { tg = 0 ; 2 for i = 0 to n-1 do tg = tg + (n-i) Xi ; return tg ; } + Daïng haøm ñeä quy tính Xn treân ngoân ngöõ Pascal laø : function X( n :integer) : integer ; var i , tg : integer ; begin if ( n= 0 ) then X := 1 else begin tg = 0 ; for i: = 0 to n-1 do tg : = tg + sqr(n-i) *X(i) ; X := tg ; end ; end ; + Daïng haøm ñeä quy tính Xn treân ngoân ngöõ C++ laø : int X( int n ) ; { if ( n == 0 ) return 1 ; else { int tg = 0 ; for (int i = 0 ; i<n ; i++ ) tg = tg + sqr(n-i) *X(i); return ( tg ) ; } Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 16 - CHÖÔNG II BAØI TOAÙN ÑEÄ QUY I. CAÙC NOÄI DUNG CAÀN LAØM ÑEÅ TÌM GIAÛI THUAÄT ÑEÄ QUY CHO MOÄT BAØI TOAÙN. Ñeå xaây döïng giaûi thuaät giaûi moät baøi toaùn coù tính ñeä quy baèng phöông phaùp ñeä quy ta caàn thöïc hieän tuaàn töï 3 noäi dung sau : - Thoâng soá hoùa baøi toaùn . - Tìm caùc tröôøng hôïp neo cuøng giaûi thuaät giaûi töông öùng . - Tìm giaûi thuaät giaûi trong tröôøng hôïp toång quaùt baèng phaân raõ baøi toaùn theo kieåu ñeä quy. 1. Thoâng soá hoaù baøi toaùn. Toång quaùt hoùa baøi toaùn cuï theå caàn giaûi thaønh baøi toaùn toång quaùt (moät hoï caùc baøi toaùn chöùa baøi toaùn caàn giaûi ),tìm ra caùc thoâng soá cho baøi toaùn toång quaùt ñaëc bieät laø nhoùm caùc thoâng soá bieåu thò kích thöôùc cuûa baøi toaùn – caùc thoâng soá ñieàu khieån ( caùc thoâng soá maø ñoä lôùn cuûa chuùng ñaëc tröng cho ñoä phöùc taïp cuûa baøi toaùn , vaø giaûm ñi qua moãi laàn goïi ñeä qui ) . Ví duï : n trong haøm FAC(n) ; a , b trong haøm USCLN(a,b) . 2. Phaùt hieän caùc tröôøng hôïp suy bieán (neo) vaø tìm giaûi thuaät cho caùc tröôøng hôïp naøy. Ñaây laø caùc tröôøng hôïp suy bieán cuûa baøi toaùn toång quaùt , laø caùc tröông hôïp töông öùng vôùi caùc gía trò bieân cuûa caùc bieán ñieàu khieån (tröôøng hôïp kích thöôùc baøi toaùn nhoû nhaát), maø giaûi thuaät giaûi khoâng ñeä qui (thöôøng raát ñôn giaûn). Ví duï : FAC(1) =1 , USCLN(a,0) = a , SM(a[x:x] ≡∅ ,TSUM(a[m:m]) = a[m] 3. Phaân raõ baøi toaùn toång quaùt theo phöông thöùc ñeä quy. Tìm phöông aùn (giaûi thuaät ) giaûi baøi toaùn trong tröôøng hôïp toång quaùt baèng caùch phaân chia noù thaønh caùc thaønh phaàn maø hoaëc coù giaûi thuaät khoâng ñeä quy hoaëc laø baøi toaùn treân nhöng coù kích thöôùc nhoû hôn. Ví duï : FAC(n) = n * FAC(n -1) . Tmax(a[1:n]) = max(Tmax(a[1:(n-1)]) , a[n] ) Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 17 - II. MOÄT SOÁ BAØI TOAÙN GIAÛI BAÈNG GIAÛI THUAÄT ÑEÄ QUY ÑIEÅN HÌNH. 1. Baøi toaùn thaùp Haø Noäi . Truyeàn thuyeát keå raèng : Moät nhaø toaùn hoïc Phaùp sang thaêm Ñoâng Döông ñeán moät ngoâi chuøa coå ôû Haø Noäi thaáy caùc vò sö ñang chuyeån moät choàng ñóa quùy goàm 64 ñóa vôùi kích thöôùc khaùc nhau töø coät A sang coät C theo caùch : - Moãi laàn chæ chuyeån 1 ñóa . - Khi chuyeån coù theå duøng coät trung gian B . - Trong suoát quùa trình chuyeån caùc choàng ñóa ôû caùc coät luoân ñöôïc xeáp ñuùng (ñóa coù kích thöôùc beù ñöôïc ñaët treân ñóa coù kích thöôùc lôùn ) . Khi ñöôïc hoûi caùc vò sö cho bieát khi chuyeån xong choàng ñóa thì ñeán ngaøy taän theá !. Nhö seõ chæ ra sau naøy vôùi choàng goàm n ñóa caàn 2n - 1 laàn chuyeån cô baûn (chuyeån 1 ñóa ). Giaû söû thôøi gian ñeå chuyeån 1 ñæa laø t giaây thì thôøi gian ñeå chuyeån xong choàng 64 ñóa seõ laø : T = ( 264 − 1 ) * t S = 18.*4 1019 *t S Vôùi t = 1/100 s thì T = 5.8*109 naêm = 5.8 tyû naêm . Ta coù theå tìm thaáy giaûi thuaät (daõy caùc thao taùc cô baûn ) cho baøi toaùn moät caùch deã daøng öùng vôùi tröôøng hôïp choàng ñóa goàm 0, 1, 2, 3 ñóa . Vôùi choàng 4 ñóa giaûi thuaät baøi toaùn ñaõ trôû neân phöùc taïp . Tuy nhieân giaûi thuaät cuûa baøi toaùn laïi ñöôïc tìm thaáy raát deã daøng nhanh choùng khi ta khaùi quaùt soá ñóa laø n baát kyø vaø nhìn baøi toaùn baèng quan nieäm ñeä quy . a) Thoâng soá hoùa baøi toaùn . Xeùt baøi toaùn ôû möùc toång quaùt nhaát : chuyeån n (n>=0) ñóa töø coät X sang coät Z laáy coät Y laøm trung gian . Ta goïi giaûi thuaät giaûi baøi toaùn ôû möùc toång quaùt laø thuû tuïc THN(n ,X ,Y,Z) chöùa 4 thoâng soá n,X,Y,Z ; n thuoäc taäp soá töï nhieân N (kieåu nguyeân khoâng daáu ); X ,Y,Z thuoäc taäp caùc kyù töï (kieåu kyù töï ). Baøi toaùn coå ôû treân seû ñöôïc thöïc hieän baèng lôøi goïi THN(64,A,B,C) . Deã thaáy raèng : trong 4 thoâng soá cuûa baøi toaùn thì thoâng soá n laø thoâng soá quyeát ñònh ñoä phöùc taïp cuûa baøi toaùn ( n caøng lôùn thì soá thao taùc chuyeån ñæa caøng nhieàu vaø thöù töï thöïc hieän chuùng caøng khoù hình dung ) , n laø thoâng soá ñieàu khieån . b) Tröôøng hôïp suy bieán vaø caùch giaûi . Vôùi n =1 baøi toaùn toång quaùt suy bieán thaønh baøi toaùn ñôn giaûn THN (1,X,Y,Z) : tìm daõy thao taùc ñeå chuyeån choàng 1 ñóa töø coät X sang coät Z laáy coät Y laøm trung gian . Giaûi thuaät giaûi baøi toaùn THN (1,X,Y,Z) laø thöïc hieän chæ 1 thao taùc cô baûn : Chuyeån 1 ñóa töø X sang Z ( kyù hieäu laø Move (X , Z) ) . Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 18 - THN(1,X,Y,Z) ≡ { Move( X, Z ) } Chuù yù : Hoaøn toaøn töông töï ta cuõng coù theå quan nieän tröôøng hôïp suy bieán laø tröôøng hôïp n= 0 töông öùng vôùi baøi toaùn THN(0,X,Y,Z) : chuyeån 0 ñóa töø X sang Z laáy Y laøm trung gian maø giaûi thuaät töông öùng laø khoâng laøm gì caû ( thöïc hieän thao taùc roãng ) . THN(0,X,Y,Z) ≡ { φ } c) Phaân raõ baøi toaùn : Ta coù theå phaàn raõ baøi toaùn TH N (k,X,Y,Z) : chuyeån k ñóa töø coät X sang coät Z laáy coät Y laøm trung gian thaønh daõy tuaàn töï 3 coâng vieäc sau : + Chuyeån (k -1) ñóa töø coät X sang coät Y laáy coät Z laøm trung gian : THN (k -1,X,Z,Y) (baøi toaùn THN vôùi n = k-1,X= X , Y = Z , Z = Y ) + Chuyeån 1 ñóa töø coät X sang coät Z : Move ( X, Z ) (thao taùc cô baûn ). + Chuyeån (k - 1 ) ñóa töø coät Y sang coät Z laáy coät X laøm trung gian : THN( k -1,Y,X,Z) ( baøi toaùn THN vôùi n = k-1 , X = Y , Y = X , Z = Z ) . Vaäy giaûi thuaät trong tröôøng hôïp toång quaùt (n > 1) laø : THN(n,X,Y,Z) ≡ { THN (n -1,X,Z,Y) ; Move ( X, Z ) ; THN (n -1,Y,X,Z) ; } Vôùi n ñóa thì caàn bao nhieâu böôùc chuyeån 1 ñóa? Thöïc chaát trong thuû tuïc THN caùc leänh goïi ñeä qui chæ nhaèm saép seáp trình töï caùc thao taùc chuyeån 1 ñóa Soá laàn chuyeån 1 ñóa ñöôïc thöïc hieän laø ñaëc tröng cho ñoä phöùc taïp cuûa giaûi thuaät . Vôùi n ñóa , goïi f(n) laø soá caùc thao taùc chuyeån _moät_ñóa . Ta coù : f(0) = 0 . f(1) =1 . f(n) = 2f(n -1) + 1 vôùi n > 0 Do ño ù : f(n) = 1+ 2 + 2 2 + + 2 n-1 = 2 n - 1 Ñeå chuyeån 64 ñóa caàn 2 64 - 1 böôùc hay xaáp xæ 10 20 böôùc . Caàn khoaûng 10 trieäu naêm vôùi moät maùy tính nhanh nhaát hieän nay ñeå laøm vieäc naøy . d) Chöông trình con maõ hoùa giaûi thuaät THN trong NNLT Pascal : procedure THN (n : integer ; X,Y,Z : char) begin if n > 0 then begin THN (n-1 ,X,Z,Y) ; Move( X, Z); THN (n-1 ,Y,X,Z); end ; end ; ( Laáy tröôøng hôïp chuyeån n = 0 laøm tröôøng hôïp neo ) Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 19 - Hoaëc : procedure THN (n : integer ; X,Y,Z : char) begin if (n = 1) then Move(X, Z) else begin THN (n-1 ,X,Z,Y ) ; Move(X, Z ); THN (n -1 ,Y,X,Z ); end ; end; ( Laáy tröôøng hôïp chuyeån n = 1 laøm tröôøng hôïp neo ) Vôùi thuû tuïc Move(X, Y) moâ taû thao taùc chuyeån 1 ñóa töø coät X sang coät Y ñöôïc vieát tuyø theo caùch theå hieän thao taùc chuyeån . e) Chöông trình con maõ hoùa giaûi thuaät THN trong NNLT C++ : Trong C++ haøm con thöïc hieän giaûi thuaät THN coù daïng : void THN( int n , char X,Y,Z) { if(n > 0) { THN(n -1,X,Z,Y ) ; Move ( X , Z ) ; THN(n - 1,Y,X,Z ) ; } return ; } hoaëc : void THN( int n , char X,Y,Z) { if(n = = 1) Move ( X , Z ) ; else { THN(n -1,X,Z,Y ) ; Move ( X, Z ) ; THN(n - 1,Y,X,Z ) ; } return ; } 2. Baøi toaùn chia thöôûng. Coù 100 phaàn thöôûng ñem chia cho 12 hoïc sinh gioûi ñaõ ñöôïc xeáp haïng. Coù bao nhieâu caùch khaùc nhau ñeå thöïc hieän caùch chia? Ta thaáy ngay raèng vieäc tìm ra lôøi giaûi cho baøi toaøn seû khoâng deã daøng neáu ta khoâng tìm ra caùch thích hôïp ñeå tieáp caän vôùi noù. Ta seõ tìm giaûi thuaät giaûi baøi toaøn baèng phöông phaùp ñeä quy. Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 20 - a) Thoâng soá hoùa. Ta seõ giaûi baøi toaùn ôû möùc ñoä toång quaùt : Tìm soá caùch chia m vaät (phaàn thöôûng ) cho n ñoái töôïng (hoïc sinh ) coù thöù töï . Goïi PART laø soá caùch chia khi ñoù PART laø haøm cuûa 2 bieán nguyeân m , n ( PART(m ,n )) . Ta maõ hoaù n ñoái töôïng theo thöù töï xeáp haïng 1, 2 , 3 , . . . n ; Si laø soá phaàn thöôûng maø hoïc sinh i nhaän ñöôïc . Khi ñoù caùc ñieàu kieän raøng buoäc leân caùch chia laø : Si >= 0 S1 >= S2 >= >= Sn . S1 + S2 + + Sn = m Ví duï : Vôùi m = 5 , n = 3 ta coù 5 caùch chia sau : 5 0 0 4 1 0 3 2 0 3 1 1 2 2 1 Töùc laø PART(5,3 ) = 5 b) Caùc tröôøng hôïp suy bieán : + m = 0 thì seû coù duy nhaát 1 caùch chia : moïi hoïc sinh ñeàu nhaän ñöôïc 0 phaàn thöôûng . Vaäy : PART(0 , n ) = 1 vôùi moïi n + n = 0 , m 0 . ( ta coù theå thay tröôøng hôïp neo PART(m ,0) = 0 hoaëc tröôøng hôïp neo PART(m , 1) = 1 ) c ) Phaân raõ baøi toaùn trong tröôøng hôïp toång quaùt : + m m thì PART(m , n ) = PART(m , m ) . + Trong tröôøng hôïp m >= n : soá vaät chia (phaàn thöôûng ) lôùn hôn hoaëc baèng soá hoïc sinh (ñoái töôïng ) ta phaân caùc caùch chia laøm 2 nhoùm : * Nhoùm thöù nhaát khoâng daønh cho hoïc sinh xeáp cuoái cuøng phaàn thöôûng naøo caû ( Sn = 0 ) . Soá caùch chia naøy seõ baèng soá caùch chia m phaàn thöông cho n -1 hoïc sinh . Töùc laø : Soá caùch chia trong nhoùm thöù nhaát = PART(m , n -1 ) . Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 21 - * Nhoùm thöù 2 coù phaàn cho ngöôøi cuoái cuøng ( Sn > 0 ) . Deã thaáy raèng soá caùch chia cuûa nhoùm naøy baèng soá caùch chia m - n phaàn thöông cho n hoïc sinh ( vì phöông thöùc chia maø taát caû hoïc sinh ñeàu nhaän ñöôïc phaàn thöôûng coù theå thöïc hieän baèng caùch : cho moãi ngöôøi nhaän tröôùc 1 phaàn thöôûng roài môùi chia ). Töùc laø : Soá caùch chia trong nhoùm thöù 2 = PART(m - n , n ) . Vaäy : vôùi m>= n PART(m , n ) = PART(m , n -1 ) + PART(m - n , n ) d ) Daïng maõ giaû cuûa haøm PART(m , n ) PART(m , n ) = if(m = 0 ) then return 1 ; else if( n = 1 ) then return 1 ; else if(m < n ) then return PART(m , m) ; else return ( PART(m , n -1) + PART(m - n , n )) e) Daïng haøm PART trong NNLT Pascal Function PART(m , n : integer ) : integer ; Begin if ( (m = 0) or ( n = 1) ) then PART := 1 else if(m < n) then PART := PART(m , m ) else PART := PART(m , n -1 ) + PART(m - n , n) ; End ; g) Daïng haøm PART trong NN LT C++ int PART( int m , int n ) { if ((m == 0 ) || (n == 0) ) return 1 ; else if(m < n ) retrun ( PART(m , m )) ; else return ( PART(m , n -1 ) + PART( m -n , n ) ) ; } 3. Baøi toaùn tìm taát caû caùc hoaùn vò cuûa moät daõy phaàn töû. Baøi toaùn : Xuaát taát caû caùc hoaùn vò cuûa daõy A . Ví duï : Vôùi daõy A goàm N = 3 phaàn töû A[1] = a , A[2] = b , A[3] = c thì baøi toaùn baét phaûi xuaát 6 hoaùn vò coù theå cuûa A : a b c a c b c b a b a c c a b b c a Vôùi daõy A goàm N = 4 phaàn töû A[1] = 1 , A[2] = 2 , A[3] = 3 , A[4] =4 thì baøi toaùn baét phaûi xuaát 24 hoaùn vò coù theå cuûa A : 1 2 3 4 1 2 4 3 1 4 3 2 4 2 3 1 Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 22 - 2 1 3 4 2 1 4 3 4 1 3 2 2 4 3 1 1 3 2 4 1 4 2 3 1 3 4 2 4 3 2 1 3 1 2 4 4 1 2 3 3 1 4 2 3 4 2 1 3 2 1 4 4 2 1 3 3 4 1 2 3 2 4 1 2 3 1 4 2 4 1 3 4 3 1 2 2 3 4 1 a) Thoâng soá hoùa baøi toaùn . Goïi HV(v, m ) ( vôùi v : array[1 . . N ] of T , m :integer ; m ≤ N ; T laø moät kieåu döõ lieäu ñaõ bieát tröôùc ) laø thuû tuïc xuaát taát caû caùc daïng khaùc nhau cuûa v coù ñöôïc baèng caùch hoaùn vò m thaønh phaàn ñaàu cuûa daõy v Ví duï : N = 4 , A[1] = 1 , A[2] = 2 , A[3] = 3 , A[4] = 4 thì lôøi goïi HV(A ,3 ) xuaát taát caû hoaùn vò cuûa A coù ñöôïc baèng caùch hoaùn vò 3 phaàn töû ñaàu ( coù 6 h vò ) : 1 2 3 4 1 3 2 4 3 2 1 4 2 1 3 4 3 1 2 4 2 3 1 4 Ñeå giaûi baøi toaùn ñaët ra ban ñaàu ta goïi HV(A,N) ). b) Tröôøng hôïp neo. Vôi m = 1 : HV(v,1) laø thuû tuïc giaûi baøi toaùn xuaát taát caû caùc daïng cuûa v coù ñöôïc baèng caùch hoaùn vò 1 phaàn tuû ñaàu . Vaäy HV(v,1) laø thuû tuïc xuaát v. HV(v,1) ≡ print(v) ≡ for k:= 1 to N do write(v[k]) c) Phaân raõ baøi toaùn. Ta coù theå tìm heát taát caû caùc hoaùn vò m phaàn töû ñaàu cuûa vector V theo caùch sau : - Giöõ nguyeân caùc phaàn töû cuoái V[m] , . . . ,V[N] hoaùn vò m-1 phaàn töû ñaàu ( goïi ñeä quy HV(V ,m - 1) . - Ñoåi choå V[m] cho V[m-1] ,giöõ nguyeân caùc phaàn töû cuoái V[m], ,V[N] hoaùn vò m-1 phaàn töû ñaàu ( goïi ñeä quy HV(V ,m - 1) . - Ñoåi choå V[m] cho V[m-2] ,giöõ nguyeân caùc phaàn töû cuoái V[m], . ,V[N] hoaùn vò m-1 phaàn töû ñaàu ( goïi ñeä quy HV(V ,m - 1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - Ñoåi choå V[m] cho V[2] ,giöõ nguyeân caùc phaàn töû cuoái V[m], . ,V[N] hoaùn vò m-1 phaàn töû ñaàu ( goïi ñeä quy HV(V ,m - 1) . - Ñoåi choå V[m] cho V[1] ,giöõ nguyeân caùc phaàn töû cuoái V[m], . . . ,V[N] hoaùn vò m-1 phaàn töû ñaàu ( goïi ñeä quy HV(V ,m - 1) . Vaäy : HV(V,m) ≡ { SWAP( V[m],V[m] ) ; HV(V,m – 1) ; SWAP( V[m],v[m-1] ) ; HV(V,m – 1) ; SWAP( V[m],v[m-2 ] ) ; HV(V,m – 1) ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 23 - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SWAP (V[m],v[2] ) ; HV(V,m – 1) ; SWAP( V[m],v[1] ) ; HV(V,m – 1) ; } ( SWAP(x , y ) laø thuû tuïc hoaùn ñoåi giaù trò cuûa 2 ñoái töôïng döõ lieäu x ,y ) Vaäy : HV(V , m ) ≡ for k := m downto 1 do begin SWAP( V[m], V[k] ) ; HV(V,m – 1) ; end ; d) Thuû tuïc hoaùn vò treân NNLT Pascal. . . . . . . . . . . . . . . . . . . const size = Val ; (* Val laø haèng gía trò *) type vector = array[1. . size] of typebase; (* typebase laø moät kieåu döõ lieäu coù thöù töï *) . . . . . . . . . . . . . . . . . . . . . . procedure Swap( var x , y : typebase ) ; var t : typebase ; begin t := x ; x := y ; y := t ; end ; . . . . . . . . . . . . . . . . . . . . . . . . . . procedure print( A : vector ) ; var i : integer ; begin for i:= 1 to size do write( A[i] : 3 ); writeln ; end ; . . . . . . . . . . . . . . . . . . . . . . . . . . Procedure HV( V : vec tor ; m :integer ) ; var k : integer ; begin if (m = 1 ) then print(V) else for k := m downto 1 do begin Swap(V[m] , V[k]); HV(V , m – 1) ; end ; end ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 24 - e) Thuû tuïc hoaùn vò treân NNLT C++ . . . . . . . . . . . . . . . . . . . const size = Val ; // Val laø haèng gía trò typedef typebase vector[size] ; // typebase laø moät kieåu döõ lieäu coù thöù töï . . . . . . . . . . . . . . . . . . . . . . void Swap( typebase & x , typebase& y) { typebase t ; t = x ; x = y ; y = t ; } . . . . . . . . . . . . . . . . . . . . . . . . . . void print( const vector &A) { for(int j= 0 ; j = 0 ; k ) { swap(V[m-1] ,V[k] ) ; HV(V,m-1) ; } } 4. Baøi toaùn saép xeáp maûng baèng phöông phaùp troän (Sort-Merge). YÙ töôûng : Ñeå saép xeáp 1 danh saùch goàm n phaàn töû baèng phöông phaùp troän ngöôøi ta chia danh saùch thaønh 2 phaàn (toång quaùt laø nhieàu phaàn ) , saép xeáp töøng phaàn, roài troän chuùng . Baøi toaùn : saép theo thöù töï khoâng giaûm maûng a : VectorT baèng phöông phaùp troän. ( VectorT = array[1 . . size] of T). a) Thoâng soá hoaù: Baøi toaùn ñöôïc khaùi quaùt thaønh saép xeáp moät daõy con cuûa daõy V : VectorT töø chæ soá m ñeán chæ soá n vôùi 1 <= m <= n <= size . Ta ñaët teân cho baøi toaùn ôû daïng toång quaùt laø : SM(V,m,n). Baøi toaùn ban ñaàu : saép daõy A seû ñöôïc thöïc hieän baèng lôøi goïi : SM(A ,1,size). b) Tröôøng hôïp taàm thöôøng: Ñoù laø khi n = m (daõy saép chæ coù 1 phaàn töû ), khi ñoù khoâng caàn laøm gì caû (thao taùc roãng) . Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 25 - c) Phaân raõ tröôøng hôïp toång quaùt : Khi n > m ta thöïc hieän caùc coâng vieäc sau : + Chia daõy : a[m] ,a[m+1], . . . , a[n] thaønh 2 daõy con a[m] , . . , a[l] vaø a[l+1] , . . . , a[n] + Saép xeáp töøng daõy con thaønh caùc daõy coù thöù töï theo giaûi thuaät SM . + Troän 2 daõy con coù thöù töï laïi thaønh daõy a[m] ,. . . , a[n] môùi coù thöù töï . Ñeå thöïc hieän vieäc troän hai daõy coù thöù töï thaønh moät daõy coù thöù töï ta seõ duøng moät thuû tuïc khoâng ñeä quy Merge(m , l , n) . Ta caàn choïn l ñeå ñöôïc 2 daõy con giaûm haün kích thöôùc so vôùi daõy ban ñaàu , töùc laø choïn l : m m then begin l := (m+n) div 2; SM (d,m,l) ; SM (d,l+1,n) ; Merge (d,m,l,n) ; end ; end ; Trong ñoù SM laø thuû tuïc troän 2 daõy taêng ñeå ñöôïc moät daõy taêng. Ñeå saép maûng A (daõy A[1:size]) ta goïi SM(A ,1,size) 5. Baøi toaùn tìm nghieäm xaáp xæ cuûa phöông trình f(x)=0 . Baøi toaùn : Haøm f(x) lieân tuïc treân ñoaïn [ao,bo] , tìm moät nghieäm xaáp xæ vôùi ñoä chính xaùc ε treân [ao,bo] cuûa phöông trình f(x) = 0. YÙ töôûng cuûa giaûi thuaät : - Tröôøng hôïp neo : bo - ao 0 thì ta xem nhö khoâng coù nghieäm xaáp xæ treân ñoaïn xeùt. - Tröông hôïp bo - ao ≥ ε thì chia ñoâi ñoaïn [ao,bo] roài tìm laàn löôït nghieäm treân töøng ñoaïn con : ñoaïn con traùi, ñoaïn con phaûi . Ta seõ xaây döïng moät haøm ñeä qui traû veà giaù trò laø nghieäm xaáp xæ cuûa f (neáu coù),hay moät haèng E ( ñuû lôùn) neáu f khoâng coù nghieäm xaáp xæ treân [ao,bo] . Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 26 - a) Thoâng soá hoaù: Xeùt haøm ROOT vôùi 3 thoâng soá laø g , a,b ,(ROOT(g,a,b)) traû veà giaù trò nghieäm xaáp xæ ε cuûa phöông trình g(x) =0 treân ñoaïn [a,b] hoaëc giaù trò C neáu phöông trình xeùt khoâng coù nghieäm xaáp xæ . Ñeå giaûi baøi toaùn ban ñaáu ta goïi haøm ROOT(f,ao,bo) . b) Tröôøng hôïp taàm thöôøng: ñoù laø khi b - a = ε ta phaân [a,b] laøm 2 ñoaïn [a,c] vaø [c,b] vôùi c = (a + b) / 2. - Neáu ROOT(g , a ,c) < E thì ROOT(g , a , b ) = ROOT(g ,a ,c) (baøi toaùn tìm nghieäm treân ñoaïn [a,c] ) . - coøn khoâng thì ROOT(g , a , b ) = ROOT(g ,c ,b) (baøi toaùn tìm nghieäm treân ñoaïn [c ,b] ) . d) Haøm tìm nghieäm xaáp xæ treân NN Pascal coù daïng: const epsilon = ; E = ; Function ROOT(a,b :real ) :real ; var c , R : real ; begin if ((b-a) < epsilon ) then if ( f(a)*f(b) <= 0 ) then ROOT := a else ROOT := L else begin c := (a + b)/2 ; if ( ROOT(a ,c ) < E ) then ROOT := ROOT(a,c) else ROOT := ROOT(c,b) end; e) Chöông trình con tìm nghieäm xaáp xæ trong NN LT C++ const double epsilon = ; const double E = ; double ROOT(double a , double b ) { if((b - a) < epsilon ) if(f(a)*f(b) <= epsilon return (a ) ; else return ( L ) ; else { double c = (a + b ) / 2 ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 27 - double R = ROOT(a,c) ; if( R< E ) return R ; else return ( ROOT(c , b) ) ; } } Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 28 - CHÖÔNG III KHÖÛ ÑEÄ QUY I. CÔ CHEÁ THÖÏC HIEÄN GIAÛI THUAÄT ÑEÄ QUY. Traïng thaùi cuûa tieán trình xöû lyù moät giaûi thuaät ôû moät thôøi ñieåm ñöôïc ñaëc tröng bôûi noäi dung caùc bieán vaø leänh caàn thöïc hieän keá tieáp. Vôùi tieán trình xöû lyù moät giaûi thuaät ñeä qui ôû töøng thôøi ñieåm thöïc hieän, con caàn löu tröõ caû caùc traïng thaùi xöû lyù ñang coøn dang dôû . a) Xeùt giaûi thuaät ñeä quy tính giai thöøa: FAC ( n ) ≡ if(n = 0 ) then retrun 1 ; else retrun ( n * FAC (n – 1)) ; Sô ñoà quaù trình tính gía trò 3 ! theo giaûi thuaät ñeä quy : FAC(3 ) = 3 * FAC( 2 ) FAC( 2 ) = 2 * FAC( 1 FAC( 1 ) = 1 * FAC( 0 FAC( 0 ) = 1 Khi thöïc hieän lôøi goïi FAC (3 ) seû phaùt sinh loøi goïi FAC (2 ) , ñoàng thôøi phaûi löu giöõ thoâng tin traïng thaùi xöû lyù coøn dang doû ( FAC ( 3 ) = 3 * FAC ( 2 ) ) . Ñeán löôït mình lôøi goïi FAC ( 2 ) laïi laøm phaùt sinh lôøi goïi FAC (1 ) ,ñoàng thôøi vaån phaûi löu tröû thoâng tin traïng thaùi xöû lyù coøn dang dôû ( FAC (2 ) = 2 * FAC ( 1 ) ) , . Cöù nhö vaäy cho tôùi khi gaëp lôøi goïi tröôøng hôïp neo ( FAC (0 ) = 1 ) . Tieáp sau quùa trình goïi laø moät quùa trình xöû lyù ngöôïc ñöôïc thöïc hieän : - Duøng giaù trò FAC ( 0 ) ñeå tính FAC ( 1 ) theo sô ñoà xöû lyù coøn löu tröû . - Duøng giaù trò FAC ( 1 ) ñeå tính FAC ( 2 ) theo sô ñoà xöû lyù coøn löu tröû . - Duøng giaù trò FAC ( 2 ) ñeå tính FAC ( 3 ) theo sô ñoà xöû lyù coøn löu tröû . Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 29 - Ñoàng thôøi vôùi quùa trình xöû lyù ngöôïc laø quùa trình xoùa boû caùc thoâng tin veà giaûi thuaät xöû lyù trung gian ( quùa trình thu hoài vuøng nhôù ) . b) Xeùt giaûi thuaät ñeä quy tính giaù trò haøm FIBONACCI . FIB(n) ≡ if ((n = 0 ) or ( n = 1 )) then return 1 ; else return ( FIB(n - 1) + FIB(n - 2)) ; Sô ñoà tính FIB(5) : FIB(5) = FIB(3) + FIB () FIB(3) = FIB(1) + FIB(2) FIB(4) = FIB(2) + FIB(3) FIB(1) = FIB(2) = FIB(0) + FIB(1) FIB(2) = FIB(0) + FIB(1) FIB(3) = FIB(2) + FIB(1) FIB(0) = FIB(1) = FIB(0) = FIB(1) = FIB(2) = FIB(0) + FIB(1) FIB(1) = FIB(0) = 1 FIB(1) = c) Xeùt thuû tuïc ñeä quy thaùp Haø Noäi THN (n , X , Y , Z) THN (n : integer ; X ,Y , Z : char) ≡ if (n > 0 ) then { THN(n-1,X ,Z ,Y) ; Move(X, Z) ; THN(n-1,Y,X,Z) ; } Ñeå chuyeån 3 ñóa töø coät A sang coät C duøng coät B laøm trung gian ta goïi : THN (3,A,B,C) Sô ñoà thöïc hieän lôøi goïi THN (3,A,B,C) laø : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 30 - Lôøi goïi c/0 Lôùi goïi c/1 Lôøi goïi c/2 Lôøi goïi c/3 THN(0,A,C,B) THN(1,A,B,C) A > C THN(0,B,A,C) THN(2,A,C,B) A > B THN(0,C,B,A) THN(1,C,A,B) C >B THN(0,A,C,B) THN(3,A,B,C) A > C THN(0,B,A,C) THN(1,B,C,A) B > A THN(0,C,B,A) THN(2,B,A,C) B > C THN(0,A,C,B) THN(1,A,B,C) A > C THN(0,B,A,C) Vôùi THN(0 ,X , Y , Z ) laø tröôøng hôïp neo töông öùng vôùi thao taùc roãng . X > Y laø thao taùc chuyeån 1 ñóa töø coät X sang coät Y (MOVE(X,Y)). Caùc böôùc chuyeån ñóa seû laø : A > C ; A > B ; C > B ; A > C ; B > A ; B > C ; A > C ; Lôøi goïi caáp 0 : THN(3 , A , B , C ) seû laøm naûy sinh hai lôøi goïi caáp 1 : THN (2 ,A, C, B) ; THN (2 , B , A , C ) cuøng vôùi caùc thoâng tin cuûa quùa trình xöû lyù coøn dang dôû . Caùc lôøi goïi caáp 1 : THN(2 , A , C , B ) , THN (2 , B , A ,C ) seû laøm naûy sinh caùc lôøi goïi caáp 2 : THN (1 ,A, B, C) ; THN (1, C , A , B ) ; THN (1 ,B, C, A) ; THN (1, A , B , C ) ; cuøng vôùi caùc thoâng tin cuûa quùa trình xöû lyù coøn dang dôû . Caùc lôøi goïi caáp 2 : THN(1 ,A, B, C) ; THN(1, C , A , B ) ; THN(1 ,B, C, A) ; THN(1, A , B , C ) ; seû laøm naûy sinh caùc lôøi goïi caáp 3 daïng : THN(0 ,X, Y, Z) (thao taùc roãng töông öùng vôùi tröôøng hôïp suy bieán ); cuøng vôùi caùc thoâng tin cuûa quùa trình xöû lyù coøn dang dôû . Quaù trình goïi döøng laïi khi gaëp tröôøng hôïp suy bieán . Quùa trình xöû lyù ngöôïc vôùi quaù trình goïi baét ñaàu khi thöïc hieän xong caùc tröôøng hôïp neo nhaèm hoaøn thieän caùc böôùc xöû lyù con dang dôû song song vôùi quaù trình hoaøn thieän caùc lôøi goïi laø quùa trình loaïi boû caùc löu tröû thoâng tin giaûi thuaät trung gian. Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 31 - Do ñaëc ñieåm cuûa quùa trình xöû lyù moät giaûi thuaät ñeä quy laø : vieäc thöïc thi lôøi goïi ñeä quy sinh ra lôøi goïi ñeä quy môùi cho ñeán khi gaëp tröôøng hôïp suy bieán (neo ) cho neân ñeå thöïc thi giaûi thuaät ñeä quy caàn coù cô cheá löu tröû thoâng tin thoûa caùc yeâu caàu sau : + ÔÛ moãi laàn goïi phaûi löu tröõ thoâng tin traïng thaùi con dang dôû cuûa tieán trình xöû lyù ôû thôøi ñieåm goïi. Soá traïng thaùi naøy baèng soá laàn goïi chöa ñöôïc hoaøn taát . + Khi thöïc hieän xong (hoaøn taát) moät laàn goïi, caàn khoâi phuïc laïi toaøn boä thoâng tin traïng thaùi tröôùc khi goïi . + Leänh goïi cuoái cuøng (öùng vôùi tröông hôïp neo) seõ ñöôïc hoaøn taát ñaàu tieân , thöù töï daõy caùc leänh goïi ñöôïc hoaøn taát ngöôïc vôùi thöù töï goïi, töông öùng daõy thoâng tin traïng thaùi ñöôïc hoài phuïc theo thöù töï ngöôïc vôùi thöù töï löu tröû . Caáu truùc döõ lieäu cho pheùp löu tröõ daõy thoâng tin thoûa 3 yeâu caàu treân laø caáu truùc löu tröû thoûa luaät LIFO (Last In Firt Out ) . Moät kieåu caáu truùc löu tröû thöôøng ñöôïc söû duïng trong tröôøng hôïp naøy laø caáu truùc choàng (stack). Vôùi moät choàng S thöôøng cho pheùp chuùng ta thöïc hieän caùc thao taùc sau treân noù : - Thuû tuïc Creatstack(S) : Taïo choàng S roãng . - Thuû tuïc Push(x,S) : Löu tröõ theâm döõ lieäu x vaøo ñónh stack S ( x laø döõ lieäu kieåu ñôn giaûn giaûn hoaëc coù caáu truùc ) - Thuû tuïc Pop(x,S) : Laáy giaù trò ñang löu ôû ñónh S chöùa vaøo trong ñoái töôïng döõ lieäu x vaø loaïi boû giaù trò naøy khoûi S ( luøi ñænh S xuoáng moät möùc ) . - Haøm Empty(S) : ( kieåu boolean ) Kieåm tra tính roãng cuûa S : cho giaù trò ñuùng neáu S roãng , sai neáu S khoâng roãng . Caøi ñaët cuï theå cuûa S coù theå thöïc hieän baèng nhieàu phöông phaùp phuï thuoäc vaøo töøng ngoân ngöõ laäp trình vaø töøng muïc ñích söû duïng cuï theå . Ví duï : Caøi ñaët ( baèng caáu truùc maûng ) choàng S maø moãi phaàn töû laø moät ñoái töôïng döõ lieäu thuoäc kieåu T trong PASCAL nhö sau : Const sizestack = . . . ; Type stackType = record St : array [1 . . sizestack ] of T ; Top : 0 . . sizestack ; end ; Thuû tuïc Creatstack(S) : taïo choàng S roãng : Procedure Creatstack( var S : StackType ) Begin S.Top := 0 ; End; Thuû tuïc Push(x,S) : Cheøn - Löu tröõ theâm döõ lieäu x vaøo ñónh stack S ( x laø döõ lieäu kieåu ñôn giaûn giaûn hoaëc coù caáu truùc ) Procedure Push( var S : StackType ; x : T) ; Begin Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 32 - S.St[S.Top +1] := x ; S.Top := S.Top + 1 ; End; Thuû tuïc Pop(x,S) : Xoùa - Laáy giaù trò ñang löu ôû ñónh S chöùa vaøo trong ñoái töôïng döõ lieäu x vaø loaïi boû giaù trò naøy khoûi S ( luøi ñænh S xuoáng moät möùc ) . Procedure Pop( var S : StackType ; var x : T ) ; Begin x := S.St[S.Top] ; S.Top := S.Top - 1 ; End; Haøm Empty(S) : ( Haøm boolean ) Kieåm tra tính roãng cuûa Stack S Function Empty( S : StackType ) : boolean ; Begin Empty := ( S.Top = 0 ) ; End ; Moâ hình stack S vaø taùc duïng caùc thao taùc treân noù . ––––––––– ––––––––– ––––––––– ––––––––– ––––––––– ––––––––– ––––––––– ––––––––– ––––––––– ––––––––– ––––––––– ––––––––– 3 ––––––––– 3 ––––––––– 3 ––––––––– 3 ––––––––– 2 ––––––––– 2 ––––––––– 2 –– x 1 ––– 2 ––––––––– 1 ––––––––– 1 –––x o –– 1 –––x o –––– 1 –––x o –––– Createstack(S) ; Push(S, xo ) ; Push(S,x1 ) ; pop(S,y) ( S.top = 0 ) S.St[1] := xo S.St[2] := x1 y := x1 S.top := 1 S.top := 2 S.Top := 1 ; NNLT PASCAL vaø C++ thöïc hieän ñöôïc cô cheá ñeä qui nhôø trong quaù trình bieân dòch, phaàn meàm ngoân ngöõ töï ñoäng phaùt sinh ra caáu truùc stack ñeå quaûn lyù caùc leänh goïi chöông trình con. Khi moät leänh goïi chöông trình con thöïc hieän, caùc bieán ñòa phöông (goàm caû caùc thoâng soá) seõ ñöôïc caáp phaùt vuøng nhôù môùi ôû ñænh stack. Nhôø vaäy caùc taùc ñoäng ñòa phöông cuûa thuû tuïc seõ khoâng laøm thay ñoåi caùc traïng thaùi xöû lyù coøn dang dôû. II. TOÅNG QUAN VEÀ VAÁN ÑEÀ KHÖÛû ÑEÄ QUY. Ñeä quy laø phöông phaùp giuùp chuùng ta tìm giaûi thuaät cho caùc baøi toaùn khoù . Giaûi thuaät giaûi baøi toaùn baèng ñeä quy thöôøng raát ñeïp (goïn gaøng, deã hieåu ,deã chuyeån thaønh Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 33 - chöông trình treân caùc NNLT) . Nhöng nhö ñaõ chæ ra ôû treân vieäc xöû lyù giaûi thuaät ñeä quy laïi thöôøng gaây khoù khaên cho maùy tính (toán khoâng gian nhôù vaø thôøi gian xöû lyù), hôn nöõa khoâng phaûi moïi NNLT ñeàu cho pheùp maõ hoùa giaûi thuaät ñeä quy (ví duï : FORTRAN) . Vì vaäy vieäc thay theá moät chöông trình ñeä quy ( coù chöùa chöông trình con ñeä quy ) baèng moät chöông trình khoâng ñeä quy cuõng laø moät vaán ñeà ñöôïc quan taâm nhieàu trong laäp trình . Moät caùch toång quaùt ngöôøi ta ñaõ chæ ra raèng : Moïi giaûi thuaät ñeä quy ñeàu coù theå thay theá baèng moät giaûi thuaät khoâng ñeä quy . Vaán ñeà coøn laïi laø kyõ thuaät xaây döïng giaûi thuaät khoâng ñeä quy töông öùng thay theá giaûi thuaät ñeä quy . Raát ñaùng tieác vieäc xaäy döïng giaûi thuaät khoâng ñeä quy thay theá cho moät giaûi thuaät ñeä quy ñaõ coù laïi laø moät vieäc khoâng phaûi bao giôø cuõng ñôn giaûn vaø ñeán nay vaãn chöa coù giaûi phaùp thoûa ñaùng cho tröôøng hôïp toång quaùt. Sô ñoà ñeå xaây döïng chöông trình cho moät baøi toaùn khoù khi ta khoâng tìm ñöôïc giaûi thuaät khoâng ñeä quy thöôøng laø : + Duøng quan nieäm ñeä quy ñeå tìm giaûi thuaät cho baøi toaùn . + Maõ hoùa giaûi thuaät ñeä quy . + Khöû ñeä quy ñeå coù ñöôïc moät chöông trình khoâng ñeä quy . Tuy nhieân do vieäc khöû ñeä quy khoâng phaûi bao giôø cuõng deã vaø vì vaäy trong nhieàu tröôøng hôïp ta cuõng phaûi chaáp nhaän sö duïng chöông trình ñeä quy . III. CAÙC TRÖÔØNG HÔÏP KHÖÛ ÑEÄ QUY ÑÔN GIAÛN. 1. Caùc tröôøng hôïp khöû ñeä quy baèng voøng laëp . a) Haøm tính gía tri cuûa daõy döõ lieäu moâ taû baèng hoài quy . a1) YÙ töôûng daãn daét : Xeùt moät voøng laëp trong ñoù söû duïng 1 taäp hôïp bieán W = (V , U ) goàm taäp hôïp U caùc bieán bò thay ñoåi trong voøng laëp vaø V laø caùc bieán coøn laïi. Daïng toång quaùt cuûa voøng laëp laø : W := Wo ; { Wo = ( Uo,Vo) } while C(U) do U := g(W) (3.1.1) Goïi Uo laø traïng thaùi cuûa U ngay tröôùc voøng laëp , Uk vôùi k >0 laø traïng thaùi cuûa U sau laàn laëp thöù k (giaû söû coøn laëp ñeán laàn k ) . Ta coù : Uo mang caùc giaù trò ñöôïc gaùn ban ñaàu Uk = g(W) = g(Uk-1 , Vo ) = f(uk-1) vôùi k = 1 n (3.1.2) Vôùi n laø laàn laëp cuoái cuøng , töùc C(Uk ) ñuùng vôùi moïi k < n , C(Un) sai Sau voøng laëp W mang noäi dung (Un ,Vo ) . Ta thaáy : ñeå tính gía trò daõy ñöôïc ñònh nghóa bôûi quan heä hoài quy daïng (3.1.2) ta coù theå duøng giaûi thuaät laëp moâ taû bôûi ñoaïn leänh (3.1.1) . a2) Giaûi thuaät tính gía trò cuûa daõy hoài quy thöôøng gaëp daïng : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 34 - f(n) = C khi n = no ( C laø moät haèng ) = g(n,f(n -1)) khi n > no Ví duï : Haøm giai thöøa FAC (n) = n ! = 1 khi n = 0 = n * FAC(n - 1) khi n > 0 Toång n soá ñaàu tieân cuûa daõy ñan daáu sau : n+1 Sn = 1 - 3 + 5 - 7 + (-1) * (2n-1) S(k) = 1 khi k =1 = S(k-1) + (- 1)k+1 *(2*k-1) vôùi k > 1 - Giaûi thuaät ñeä quy tính giaù trò f(n) f(n) = if(n = no) then return C ; else return (g(n,f(n -1)) ; - Giaûi thuaät laëp tính giaù tri f(n) k := no ; F := C ; { F = f(no) } While( k < n ) do begin k := k +1 ; F := g(k,F ) ; end ; } { F = f(n) } Hoaëc : F := C ; For k := no to n -1 do begin k := k + 1 ; F := g(k,F) ; end ; Trong tröôøng hôïp naøy : W = U = ( k ,F ) Wo = Uo = ( no,C ) C(U) = ( k < n) f(W) = f(U) = f(k,F) = (k+1,g(k,F))) Ví duï 1: Haøm tính FAC(n) = n! khoâng ñeä quy + Trong NN LT PASCAL Function FAC ( n : integer ) : longint ; var k : integer ; F : longint ; Begin F := 1 ; k := 0 ; while (k < n ) do begin Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 35 - k := k + 1 ; F := F * k ; end ; FAC := F ; end ; hoaëc : Function FAC ( n : integer ) : longint ; var k : integer ; F : longint ; Begin F := 1 ; For k:= 1 to n do F := F * k ; FAC := F ; end ; + Trong NN LT C++ long int FAC ( int n ) { int k = 0 ; long int F = 1 ; while ( k < n ) F = ++k * F ; return (F) ; } Hoaëc : long int FAC ( int n ) { long int F = 1 ; for ( int k = 1; k <= n ; k++) F = k * F ; return (F) ; } Ví du 2 : Daïng haøm Sn khoâng ñeä quy + treân NN LT Pascal : Function S(n : integer ) : integer ; var k ,tg : integer ; Begin k := 1 ; tg := 1 ; while ( k < n ) do begin k := k + 1 ; if odd (k) then tg := tg + (2 * k - 1 ) else tg := tg - (2 * k - 1 ) ; end ; S := tg ; end ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 36 - + Trong NN LT C++ int S ( int n ) { int k = 1 , tg = 1 ; while ( k < n ) { k ++ ; if (k%2) tg + = 2 * k - 1 ; else tg - = 2 * k + 1 ; } return ( tg ) ; } b) Caùc thuû tuïc ñeä qui daïng ñeä qui ñuoâi. Xeùt thuû tuïc P daïng : P(X) ≡ if B(X) then D(X) else { A(X) ; P(f(X)) ; } Trong ñoù : X laø taäp bieán ( moät hoaëc moät boä nhieàu bieán ). P(X) laø thuû tuïc ñeä quy phuï thuoäc X A(X) ; D(X) laø caùc nhoùm thao taùc (leänh ) khoâng ñeä quy f(X) laø haøm bieán ñoåi X Xeùt quùa trình thi haønh P(X) : goïi Po laø laàn goïi P thöù 0 (ñaàu tieân ) P(X) P1 laø laàn goïi P thöù 1 (laàn 2) P(f(X)) Pi laø laàn goïi P thöù i ( laàn i + 1) P(f(f( f(X) ) ( P(fi(X)) hôïp i laàn haøm f ) Trong laàn goïi Pi neáu B(fi(X)) khoâng ñuùng (false) thì thi haønh leänh A vaø goïi Pi+1 ; neáu B(fi(X)) ñuùng (true) thì thi haønh leänh D vaø keát thuùc quùa trình goïi . Giaû söû P ñöôïc goïi ñuùng n +1 laàn . Khi ñoù ôû trong laàn goïi cuoái cuøng (thöù n ) Pn thì B(fn(X)) ñuùng , leänh D ñöôïc thi haønh vaø chaám döùt thao taùc goïi thuû tuïc P . Sô ñoà khoái quaù trình thöïc hieän leänh goïi thuû tuïc P(X) coù daïng sau : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 37 - P(X) B(X) True A(X) ; False X : = f(X) D(X) END Töông öùng vôùi voøng laëp sau : While ( not B(X) ) do begin A(X) ; X := f(X) ; end ; D(X) ; Ví duï 1 : Ñeå ñoåi 1 soá nguyeân khoâng aâm y ôû cô soá 10 sang daïng cô soá k ( 2 0 then Begin A[m] := n mod k ; Convert(n div k , m -1) ; End ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 38 - Leänh goïi Convert(y,n) duøng ñeå ñoåi soá nguyeân y trong cô soá 10 sang cô soá k löu daõy kyù soá trong maûng A ; Trong ví duï naøy ta coù : X laø ( n, m ) ; B(X) laø bieåu thöùc boolean not( n 0) then begin A[m] := n mod k ; { A(X) } n := n div k ; { X := f(X) } m := m - 1 ; end ; Ví duï 2 : Tìm USCLN cuûa 2 soá nguyeân döïa vaøo thuaät toaùn Euclide . - Giaûi thuaät ñeä quy (döôùi daïng thuû tuïc ) tìm USCLN(m,n) baèng thuaät toaùn Euclide : USCLN(m , n , var us) ≡ if ( n = 0 ) then us := m else USCLN(n , m mod n , us ) ; - Trong tröôøng hôïp naøy thì : X laø ( m , n , us ) P(X) laø USCLN(m ,n ,us) B(X) laø n = 0 D(X) laø leänh gaùn us := m A(X) laø leänh roãng f(X ) laø f(m,n,us) = ( n , m mod n ,us ) - Ñoaïn leänh laëp töông öùng laø : While (n <> 0 ) do begin sd := m mod n ; m := n ; n := sd ; end ; us := m ; - Thuû tuïc khoâng ñeä quy töông öùng trong Pascal . Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 39 - Procedure USCLN(m , n : integer ; var us : integer ) ; var sd : integer ; begin while ( n = 1 Ta coù quan heä sau : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 40 - Uo = Xo Ui = g(Ui-1 ) i = 1 k . Vôùi k laø soá nhoû nhaát maø C(Uk ) sai . Luùc ñoù : f(Xo ) = a(Uk ) Vaäy ñoaïn chöông trình tính f = f(Xo) laø : U := Xo ; while C(U) do U := g(U) ; f := a(U) ; Ví duï : Vôùi m , n > = 0 ta coù haøm ñeä quy tính USCLN(m,n) laø : USCLN(m ,n ) ≡ if (m 0 ; g(X) = g(m ,n ) = (abs(m -n ) , min (m ,n ) ) ; a(x) = a(m ,n ) = n ; - Ñoaïn chöông trình tính USCLN(a ,b) laø : m := a ; n := b ; while ( m 0 ) do begin t1 := m ; t2 := n ; m := abs(t1 - t2 ) ; if(t1 < t2 ) then n := t1 else n := t2 ; end ; USCLN := m ; - Daïng haøm töông öùng trong C++ int USCLN(int m , int n) { while( n != 0) { int t1 = m ; int t2 = n ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 41 - m = abs(t1-t2) ; if(t1<t2) n = t1 ; else n = t2 ; } return(m) ; } 2. Khöû ñeä quy haøm ñeä quy arsac a) Daïng haøm ñeä qui ARSAC. a1) Daïng toaùn hoïc : DS(A(CS(X) ) , FS(CS(X) , X ) ) ) khi C(X) ñuùng A(X) = BS(X) khi C(X) sai a2) Daïng maõ giaû : A(X ) ≡ if C(X) then return ( DS (A(CS(X)) ,FS(CS(X),X) ) else return (BS(X ) ) Vôùi : BS , CS , DS , FS laø caùc giaûi thuaät khoâng ñeä qui . Tröôøng hôïp thöôøng gaëp laø : BS(X) , CS(Y) , DS(U,V) , FS(U,V) laø caùc thao taùc ñôn giaûn , khoâng coù leänh goïi haøm con . X , Y ,U , V laø bieán ñôn trò hoaëc bieán veùc tô . Ñaây laø daïng toång quaùt cuûa haøm ñeä quy chæ goïi ñeán chính noù moät laàn . b) Sô ñoà toång quaùt tính gía trò A(X) : Goïi Uo = X laø gía trò ñoái soá caàn tính cuûa haøm A . Vieäc tính A(Uo) seõ phaùt sinh leänh goïi tính A(U1) vôùi U1 = CS(Uo) ( gæa söû C(Uo) true ). Cöù nhö vaäy , khi maø C(Ui ) coøn ñuùng thì vieäc tính A(Ui ) seõ phaùt sinh leänh tính A(Ui+1) vôùi Ui+1 = CS(Ui ). Vôùi giaû thieát laø Uo = X thuoäc mieàn xaùc ñònh cuûa A , thì quaù trình laëp laïi caùc leänh goïi naøy phaûi döøng laïi sau höõu haïn laàn goïi . Töùc laø ∃ k thoûa : C(Uo) = C(U1) = . . = C(Uk-1) = true , C(Uk) = false. Xeùt 2 daõy soá : - Daõy : { Ui } = { CS(Ui) } ( 2.1) Uo = X { cho tröôùc } Ui+1 = CS(Ui) i = 0 . . k-1 - Daõy : { Vi } = { A(Ui) } (2.2) Vo = A(Uo) = A(Xo) ( gía trò caàn tính ). Vi = A(Ui) = DS(A(CS(Ui ), FS(CS(Ui), Ui ) ) Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 42 - = DS(A(Ui+1),FS(Ui+1,Ui)) = DS(Vi+1,FS(Ui+1,Ui)) vôùi 0< i < k ( vì C(Ui) ñuùng ) Vk = BS(Uk) ( vì C(Uk) = false ) Döïa vaøo 2 daõy soá {Ui } ,{Vi} ( moâ taû bôûi (2.1) vaø (2.2) ) ta tính A(X ) theo giaûi thuaät sau : - Tính vaø ghi nhôù caùc Ui töø 0 ñeán k theo (2.1). ( Vôùi C(Uo) = C(U1) = = C(Uk-1) = True , C(Uk) = False ) - Söû duïng daõy gía trò Ui ñeå tính laàn ngöôïc Vi töø k xuoáng 0 theo (2.2) , Vo chính laø gía trò caàn tính ( Vo = A(X ) ). c) Giaûi thuaät khoâng ñeä quy tính gía trò haøm Arsac baèng söû duïng caáu truùc Stack . Ñeå thöïc hieän giaûi thuaät treân thì daõy Ui phaûi ñöôïc tính vaø löu tröû trong moät caáu truùc döõ lieäu thích hôïp , ñeå khi caàn ñeán (khi tính Vi ) deã laáy ra söû duïng . Ñaëc ñieåm quan trong cuûa daõy Ui laø thoûa luaät LIFO : thöù töï söû duïng ngöôïc vôùi thöù töï taïo sinh . Caáu truùc döõ lieäu cho pheùp löu tröõ thuaän lôïi daõy phaàn töû thoûa luaät LIFO ( vaøo sau ra tröôùc - Last In First Out ) laø caâu truùc Stack . ( Treân caáu truùc Stack 2 thao taùc cô baûn ñaëc tröng laø : + Push(S,X) : Cheøn phaàn töû döõ lieäu X vaøo ñónh Stack S . + Pop(S,X) : Laáy ra khoûi stack S phaàn töû döõ lieäu ôû ñónh vaø chöùa noù vaøo bieán X ). Giaûi thuaät khoâng ñeä qui tính Vo = A(X) döïa treân 2 coâng thöùc (2.1 ) , (2. 2 ) vaø söû duïng Stack S laø : + Böôùc 1 : tính Ui baét ñaàu töø Uo theo (2.1) löu vaøo Stack S CreateStack(S) ; ( taïo stack roãng S ) k := 0 ; U := X ; ( Uo = X ) push(S,U) ; ( cheøn UO vaøo ñónh stack S ) while C(U) do begin k := k+1 ; U := CS(U) ; ( Uk+1 = CS(Uk)) push (S,U) ; ( cheøn Uk+1 vaøo ñónh Stack S ) end ; + Böôùc 2 : Laáy döõ lieäu trong Stack S tính Vi theo (2. 2) pop(S,U) ; ( U = Uk ) V := BS(U) ; ( C(Uk) sai ; V=Vk = BS (Uk)) for i := k -1 downto 0 do begin Y := U ; ( Y = Ui+1) Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 43 - pop(S,U) ; ( U = Ui ) V := DS(V,FS(Y,U)) ; ( C(Ui) ñuùng ; Vi = DS(Vi+1,FS(Ui+1,Ui)) ) end ; { V = A(Xo) } Hoaëc : + Böôùc 1 : tính Ui baét ñaàu töø Uo theo (2.1) löu vaøo Stack S CreateStack(S) ; ( taïo stack roãng S ) U := Xo ; ( Uo = Xo ) push(S,U) ; ( cheøn UO vaøo ñónh stack S ) while C(U) do begin U := CS(U) ; ( UK+1 = CS(UK)) push (S,U) ; ( cheøn Uk+1 vaøo ñónh Stack S ) end ; + Böôùc 2 : Laáy döõ lieäu trong Stack S tính Vi theo (2. 2) pop(S,U) ; ( U = Uk ) V := BS(U) ; ( C(Uk) sai ; V=Vk = BS (Uk)) While(not emptystack(S)) do begin Y := U ; ( Y = Ui+1) pop(S,U) ; ( U = Ui ) V := DS(V,FS(Y,U)) ; ( C(Ui) ñuùng ; Vi = DS(Vi+1,FS(Ui+1,Ui)) ) end ; { V = A(Xo) } Cô cheá löu tröû daõy döõ lieäu LIFO baèng Stack laø moät ñaëc tröng cuûa quaù trình xöû lyù giaûi thuaät ñeä quy ñieàu caàn quan taâm laø caáu truùc stack thöôøng chieám nhieàu boä nhôù . Vì vaäy ngöôøi ta luoân tìm caùch traùnh duøng noù khi coøn traùnh ñöôïc . d) Moät soá haøm Arsac ñaëc bieät maø vieäc khöû ñeä qui giaûi thuaät tính gía trò haøm coù theå khoâng duøng Stack . d1) Tröôøng hôïp thuû tuïc CS laø song aùnh . Tröôøng hôïp CS laø song aùnh töø mieàn D leân mieàn D thì haøm CS coù haøm ngöôïc CS-1 . Goïi haøm ngöôïc cuûa haøm CS laø haøm CSM1 . Ta coù : CSM1(CS(X)) = CS-1(CS(X)) = X vôùi ∀ X ∈ D . -1 Neân : CSM1(Ui+1) = CS (CS(Ui)) = Ui vôùi i = k-1, . . ,1,0 Khi ñoù ta khoâng caàn löu giöõ caùc giaù trò trung gian cuûa daõy { Ui } maø chæ caàn xuaát phaùt töø Uk duøng haøm CSM1 ñeå khoâi phuïc laïi caùc gía trò Ui voùi i<k . Giaûi thuaät tính A(X ) seõ trôû thaønh : + Böôùc 1 : Döïa vaøo (2.1) tính Uk Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 44 - U := X ; ( Uo = X ) k := 0 ; while C(U) do begin k := k+1 ; U := CS(U) ; ( UK+1 = CS(UK)) end ; + Böôùc 2 : Tính Vk , Vk-1, V1, Vo döïa vaøo Uk ,(2.2) vaø CSM1 V := BS(U) ; ( V=Vk = BS (Uk) ) for i := k -1 downto 0 do begin Y := U ; ( Y = Ui+1 ) U := CSM1(U) ; (Ui = CSM1(Ui+1) ) V := DS(V,FS(Y,U)) ; ( Vi = DS(Vi+1,FS(Ui+1,Ui) ) end ; { V = Vo = A(X )} d2) Tröôøng hôïp thuû tuïc DS coù tính hoaùn vò . Xeùt coâng thöùc tính : Vi = DS(Vi+1,FS(Ui+1,Ui)) vôùi moïi i<k Ñaët : U’i = FS(Ui+1,Ui ) DS(Vi+1,U’i) = Vi+1 T U’i Ta coù : Vo = DS(V1, FS(U1,Uo) = DS(V1,U’o) = V1 T U’0 V1 = DS(V2, FS(U2,U1) = DS(V2,U’1) = V2 T U’1 V2 = DS(V3, FS(U3,U2) = DS(V3,U’2) = V3 T U’2 Vi = DS(Vi+1, FS(Ui+1,Ui) = DS(Vi+1,U’i) = Vi+1 T U’i ( 3 - 1 ) Vk-1 = DS(Vk, FS(Uk,Uk-1) = DS(Vk,U’k-1) = Vk T U’k-1 Vk = BS(Uk) Khi DS coù tính hoaùn vò töùc : DS(DS(x,y),z) = DS(DS(x,z),y) ( Vieát treân kyù hieäu T : (x T y) T z = (x T z) T y Thöïc hieän theá laàn löôït V1 roài V2 trong coâng thöùc Vo. Ta coù : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 45 - Vo = V1 T U’0 = ( V2 T U’1) T Uo = ( V2 T U’0 ) T U’1 = ( ( V3 T U’2) T U’o) T U’1 = ((V3 T U’2) T U’o ) T U’1 = ( (V3 T U’o) T U’2 ) T U’1 = ( (V3 T U’o) T U’1 ) T U’2 V0 = ( ((( Vk T U’o) T U’1) T U’2 ) T T U’k-2) T U’k-1 (3 - 2 ) (3 - 2) laø moät daõy lieân tieáp ( moät toång ) k pheùp toaùn T maø ta ñaõ bieát giaûi thuaät tính. Thöïc vaäy : Thieát laäp daõy Wi nhö sau : W0 = Vk Wi = Wi-1 T U’i-1 vôùi i = 1 k Töùc laø : Wo = Vk = BS(Uk ) (3 - 3 ) Wi = Wi-1 T U’i-1 = DS(Wi-1,FS(Ui,Ui-1)) i=1 k Wk chính laø gía trò Vo caàn tính . Nhö vaäy giaûi thuaät tính Wk ( Vo = A(X ) ) goàm 2 böôùc : Böôùc 1: Xaùc ñònh k vaø Uk theo coâng thöùc ( 1 - 1 ) Böôùc 2: Tính daõy Wi , trong luùc tính thì phaûi tính laïi daõy Ui ,theo ( 3 - 3) A(X ) = Vo = Wk . Giaûi thuaät khoâng ñeä qui töông öùng döôïc xem nhö baøi taäp . 3. Khöû ñeä quy moät soá daïng thuû tuïc ñeä quy thöôøng gaëp. a) Daãn nhaäp. Ñeå thöïc hieän moät chöông trình con ñeä quy thì heä thoáng phaûi toå chöùc vuøng löu trữ thoûa quy taéc LIFO (vuøng Stack). Vì vaäy chæ nhöõng ngoân ngöõ laäp trình coù khaû naêng taïo vuøng nhôù stack môùi cho pheùp toå chöùc caùc chöông trình con ñeä quy. Thöïc hieän moät chöông trình con ñeä quy theo caùch maëc ñònh thöôøng toán boä nhôù vì caùch toå chöùc Stack moät caùch maëc ñònh thích hôïp cho moïi tröôøng hôïp thöôøng laø khoâng toái öu trong töøng tröôøng hôïp cuï theå. Vì vaäy seû raát coù ích khi ngöôøi laäp trình chuû ñoäïng taïo ra caáu truùc döõ lieäu stack ñaëc duïng cho töøng chöông trình con ñeä quy cuï theå . Phaàn tieàp theo seû trình baøy vieäc khöû ñeä quy moät soá daïng thuû tuïc ñeä quy theo höôùng thay giaûi thuaät ñeä quy baèng caùc voøng laëp vaø moät caáu truùc döõ lieäu kieåu stack thích hôïp . b) Thuû tuïc ñeä qui chi coù moät leänh goïi ñeä quy tröïc tieáp . Moâ hình toång quaùt cuûa thuû tuïc ñeä quy chæ coù moät leänh goïi ñeä quy tröïc tieáp laø : P(X) ≡ if C(X) then D(X) Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 46 - else begin A(X) ; P(f(X)) ; B(X) ; end ; Vôùi : X laø moät bieùn ñôn hoaëc bieán veùc tô. C(X) laø moät bieåu thöùc boolean cuûa X . A(X) , B(X) , D(X) laø caùc nhoùm leänh khoâng ñeä quy ( khoâng chöùa leänh goïi ñeán P ). f(X) laø haøm cuûa X . Tieán trình thöïc hieän thuû tuïc P(X) seû laø : + Neáu C(X) ñuùng thì thöïc hieän D(X) . + Coøn khoâng ( C(X) sai ) thì thöïc hieän A(X) ; goïi P(f(X)) ; thöïc hieän B(X) . ( B(X) chæ ñöôïc thöïc hieän khi P(f(X)) thöïc hieän xong ) . Moãi laàn thaønh phaàn ñeä quy P(Y) ñöôïc goïi thì thoâng tin giaûi thuaät B(Y) laïi ñöôïc sinh ra (nhöng chöa thöïc hieän ) . Gæa söû quùa trình ñeä quy keát thuùc sau k laàn goïi ñeä quy thì ta phaûi thöïc hieän moät daõy k thao taùc B theo thöù töï : B(fk-1(X)) , B(fk-2(X)) , . . . ,B(f(f(X))) ,B(f(X)),B(X). Ñeå thöïc hieän daõy thao taùc { B(fi(X)) } theo thöù töï ngöôïc vôùi thöù töï phaùt sinh ta caàn daõy döõ lieäu {fi(X) } truy xuaát theo nguyeân taéc LIFO. Ta seû duøng moät Stack ñeå löu tröû daõy { fi(X) } ≡ { X , f(X) , f(f(X)) , . . . , fi(X) , . . . , fk-1(X) } Trình töï thöïc hieän P(X) ñöôïc dieãn taû baèng moâ hình sau : P(X) C(X) = False A(X) ; Push(S,X); U:=f(X) ; P(U) ; POP(S,U) ; B(U) ( U = X ) C(U) = False A(U) ; Push(S,U); U :=f(U)); P(U) ; POP(S,U) ; B(U) ( U = f(X)) C(U) = False A(U) ; Push(S,U) ; U : = f(U)); P(U ) ; POP(S,U) ; B(U) C(U) = False A(U) ; > Push(S,U) ; U : = f(U)); P(U ) ; POP(S,U) ; B(U) k-1 ( U=f (X) ) C(U) = True D(U ) Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 47 - Giaûi thuaät thöïc hieän P(X) vôùi vieäc söû duïng Stack coù daïng : P(X) ≡ { Creat_Stack (S) ; ( taïo stack S ) While(not(C(X)) do begin A(X) ; Push(S,X) ; ( caát gía trò X vaøo stack S ) X := f(X) ; end ; D(X) ; While(not(EmptyS(S))) do begin POP(S,X) ; ( laáy döõ lieäu töø S ) B(X) ; end ; } Ví duï : Thuû tuïc ñeä quy chuyeån bieåu dieãn soá töø cô soá thaäp phaân sang nhò phaân coù daïng : Binary(m) ≡ if ( m > 0 ) then begin Binary( m div 2 ) ; write( m mod 2 ) ; end; Trong tröôøng hôïp naøy : X laø m . P(X) laø Binary(m) . A(X) ; D(X) laø leänh roãng . B(X) laø leänh Write(m mod 2 ) ; C(X) laø ( m 0 ) do begin sdu := m mod 2 ; Push(S,sdu) ; m := m div 2 ; end; While( not(EmptyS(S)) do begin POP(S,sdu) ; Write(sdu) ; end; } Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 48 - c) Nhieàu leänh goïi ñeä quy tröïc tieáp. c1) Thuû tuïc ñeä quy vôùi 2 laàn goïi tröïc tieáp Thuû tuïc ñeä quy 2 laàn goïi tröïc tieáp coù daïng : P(X) ≡ if C(X) then D(X) else begin A(X) ; P(f(X)) ; B(X) ; P(g(X)) ; end ; Quùa trình thöïc hieän thuû tuïc P(X) seû laø : - Neáu C(X) ñuùng thì thöïc hieän D(X) . - Neáu C(X) sai thì thöïc hieän A(X) ; goïi P(f(X)) ; thöïc hieän B(X) ; goïi P(g(X)) , khi goïi P(g(X)) thì laïi phaùt sinh leänh A(g(X)) nhö vaäy ngoaøi vieäc phaûi löu vaøo stack caùc gía trò fi(X) ta con phaûi löu vaøo stack caùc gía trò gi(X) töông öùng . Khi ta laáy döõ lieäu töø stack ñeå thöïc hieän leänh B(U) maø chöa gaëp ñieàu kieän keát thuùc thì ta thöïc hieän P(g(U)) vaø laïi phaûi löu gía trò g(U) vaøo stack , Ñieàu kieän döøng laø khi truy xuaát tôùi phaàn töû löu ñaàu tieân trong stack . Nhö vaäy laø ngoaøi döõ lieäu X , con phaûi löu vaøo ngaên xeáp theâm thöù töï laàn goïi ( cuïm goïi ) Thuaät toaùn khöû ñeä quy töông öùng vôùi thuû tuïc ñeä quy P(X) laø : { Creat_Stact (S) : Push (S, (X,1)) ; Repeat While ( not C(X) ) do begin A(X) ; Push (S, (X,2)) ; X := f(X) ; end ; D(X) ; POP (S, (X,k)) ; if ( k <> 1) then begin B(X) ; X := g(X) ; end ; until ( k = 1 ) ; } Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 49 - Ví duï : Khöû ñeä quy thuû tuïc Thaùp Haø Noäi . + Daïng ñeä quy cuûa thuû tuïc Thaùp Haø Noäi laø : THN(n , X , Y, Z ) ≡ if( n > 0 ) then begin THN ( n - 1 , X , Z , Y ) ; Move ( X , Z ) ; THN ( n - 1 , Y , X , Z ) ; end ; Vôùi n laø soá ñóa , X laø coät ñaàu , Z laø coät cuoái , Y laø coät giöõa ,Move(X,Z) laø thao taùc chuyeån 1 ñóa töø coät X tôùi coät Z . Trong tröôøng hôïp naøy : Bieán X laø boä ( n , X , Y , Z ) . C(X) laø bieåu thöùc boolean ( n 0 ) do begin Push (S ,(n,X,Y,Z,2)) ; n := n - 1 ; Swap (Y,Z ) ; (* Swap(a,b) laø thuû tuïc hoaùn end ; ñoåi noäi dung 2 bieán a ,b *) POP (S,(n,X,Y,Z,k)) ; if ( k <> 1 ) then begin Move (X ,Z ) ; n := n - 1 ; Swap (X ,Y ) ; end ; until ( k = 1 ) ; } c2) Tröôøng hôïp n laàn goïi ñeä quy tröïc tieáp . Thuû tuïc ñeä quy trong tröôøng hôïp naøy coù daïng : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 50 - P(X) ≡ if C(X) then D(X) else begin A1(X) ; P(f1(X)) ; A2(X) ; P(f2(X)) ; Ai(X) ; P(fi(X)) ; An(X) ; P(fn(X)) ; An+1(X) ; end ; Cuõng gioáng nhö trong tröôøng hôïp (3a) laø khi quay trôû laïi sau khi thöïc hieän moät laàn ñeä quy, caàn bieát ñoù laø leänh goïi thuoäc nhoùm thöù maáy trong daõy leänh goïi ñeå bieát thao taùc caàn thöïc hieän tieáp. Vì vaäy trong choàng caàn giöõ theâm vò trí nhoùm leänh goïi . Daïng laëp töông öùng laø : { Creat_Stack (S) ; Push(S,(X,1)) ; Repeat While (not C(X) ) do begin A1(X) ; Push (S,(X,2)) ; X := f1(X) ; end ; D(X) ; POP(S,(X,k)) ; While( k = n+1 ) do begin An+1 ; POP(S,(X,k)) ; end ; if ( k > 0 ) then begin Ak(X) ; Push (S,(X,k+1)); X := f k (X) end ; until (k = 1 ) ; } Ví duï : Khöû ñeä quy cho thuû tuïc hoaùn vò . + Thuû tuïc hoaùn vò döôùi daïng ñeä quy : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 51 - HVI(V ,n) ≡ if (n = 1 ) then Print ( V ) else for i := n downto 1 do begin Swap (V[n],V[i] ) ; HVI(V ,n - 1) : end ; trong tröôøng hôïp naøy thì : X laø boä (V ,n ) . (* vector V vaø soá nguyeân n *) C(X) laø ( n = 1 ) . D(X) laø Print (V) . (* xuaát vector V *) Ai(X) laø thuû tuïc Swap(V[n] ,V[i] ) ( i = 1 n ) . An+1 laø thao taùc roãng . fi(X) = f(V, n ) = ( V, n - 1) .( vôùi i = 1 . . n ) Daïng laëp cuûa thuû tuïc laø : { Creat_Stack (S) ; Push (S,(V ,n ,1)) ; Repeat While ( n > 1 ) do begin Swap(V[n] ,V[1] ; Push (S ,V , n ,2) ; n := n -1 ; end ; Print (V) ; POP (S ,(V ,n ,k)) ; While ( k = n +1 ) do POP(S ,(V ,n ,k) ; if(k <> 1 ) then begin Swap(V[n] ,V[k]) ; Push (S ,(V ,n ,k+1) ; n := n - 1 ; end ; until(k = 1 ) ; Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 52 - PHAÀN II KIEÅM CHÖÙNG CHÖÔNG TRÌNH CHÖÔNG IV CAÙC KHAÙI NIEÄM I. CAÙC GIAI ÑOAÏN TRONG CUOÄC SOÁNG CUÛA MOÄT PHAÀN MEÀM Vieäc söû duïng maùy tính ñeå giaûi moät baøi toaùn thöïc teá thöôøng bao goàm nhieàu vieäc. Trong caùc coâng vieäc ñoù coâng vieäc maø ngöôøi ta quan taâm nhaát laø vieäc xaây döïng caùc heä thoáng phaàn meàm (caùc heä thoáng chöông trình giaûi baøi toaùn ). Ñeå xaây döïng moät heä thoáng phaàn meàm , ngöôøi ta thöôøng thöïc hieän trình töï caùc coâng vieäc sau : Ñaëc taû baøi toaùn, xaây döïng heä thoáng, söû duïng vaø baûo trì. 1) Ñaëc taû baøi toaùn Goàm vieäc phaân tích ñeå naém baét roõ yeâu caàu cuûa baøi toaùn vaø dieãn ñaït chính xaùc laïi baøi toaùn baèng ngoân ngöõ thích hôïp vöøa thích öùng vôùi chuyeân ngaønh tin hoïc vöøa coù tính ñaïi chuùng ( deã hieåu ñoái vôùi nhieàu ngöôøi). 2) Xaây döïng heä thoáng Trong böôùc naøy seû tuaàn töï thöïc hieän caùc coâng vieäc sau : - Thieát keá : Xaây döïng moâ hình heä thoáng phaàn meàm caàn coù. Trong böôùc naøy, coâng vieäc chuû yeáu laø phaân chia heä thoáng thaønh caùc module chöùc naêng vaø xaùc ñònh roõ chöùc naêng cuûa töøng module cuõng nhö moái töông taùc giöõa caùc module vôùi nhau. Chöùc naêng cuûa moãi module ñöôïc ñònh roõ bôûi ñaëc taû cuûa töøng module töông öùng. - Trieån khai töøng module vaø thöû nghieäm : Vieát chöông trình cho töøng module (baøi toaùn con) thoûa "ñuùng" ñaëc taû ñaõ ñaët ra. Tính ñuùng cuûa chöông trính ñöôïc quan taâm baèng 2 höôùng khaùc nhau : + Chöùng minh tính ñuùng moät caùch hình thöùc (thöôøng laø moät coâng vieäc khoù khaên) . + Chaïy thöû chöông trình treân nhieàu boä döõ lieäu thöû khaùc nhau moãi boä döõ lieäu ñaïi dieän cho moät lôùp döõ lieäu (thöôøng laø moät coâng vieäc toán keùm ). Ñeå coù tính thuyeát phuïc cao, ngöôøi ta caàn chaïy thöû treân caøng nhieàu boä döõ lieäu caøng toát. Khi thöû neáu phaùt hieän sai thì phaûi söûa laïi chöông trình coøn chöa phaùt hieän sai thì ta con taïm tin chöông trình ñuùng (chaïy thöû chæ coù taùc duïng phaùt hieän sai vaø taêng loøng tin vaøo tính ñuùng chöù khoâng chöùng minh ñöôïc tính ñuùng ). Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 53 - - Thöû nghieäm ôû möùc ñoä heä thoáng : Sau khi töøng module hoaït ñoäng toát, ngöoøi ta caàn thöû söï hoaït ñoäng phoái hôïp cuûa nhieàu module, thö nghieäm toaøn boä heä thoáng phaàn meàm. Thöû nghieäm tính ñuùng theo baát cöù caùch naøo thì cuõng raát toán thôøi gian vaø coâng söùc nhöng laïi laø moät vieäc phaûi laøm cuûa ngöôøi laäp trình vì ngöôøi laäp trình luoân luoân phaûi baûo ñaûm chöông trình mình taïo ra thoûa ñuùng ñaëc taû. 3) Söû duïng vaø baûo trì heä thoáng Sau khi heä thoáng phaàn meàm hoaït ñoäng oån ñònh, ngöôøi ta ñöa noù vaøo söû duïng. Trong quaù trình söû duïng coù theå coù nhöõng ñieàu chænh trong ñaëc taû cuûa baøi toaùn, hay phaùt hieän loãi sai cuûa chöông trình. Khi ñoù caàn xem laïi chöông trình vaø söûa ñoåi chuùng. Caùc yeâu caàu sau cho quùa trình xaây döïng phaàn meàm : a) Caàn xaây döïng caùc chöông trình deã ñoïc, deã hieåu vaø deã söûa ñoåi. Ñieàu naøy ñoøi hoûi moät phöông phaùp toát khi xaây döïng heä phaàn meàm : phaân raõ toát heä thoáng , söû duïng caùc caáu truùc chuaån vaø coù heä thoáng khi vieát chöông trình ,coù söu lieäu ñaày ñuû . b) Caàn ñaûm baûo tính ñuùng. Laøm theá naøo ñeå xaây döïng moät chöông trình "ñuùng" ? Moät ñieàu caàn chuù yù laø: Pheùp thöû chöông trình chæ cho khaû naêng chæ ra chöông trình sai neáu tình côø phaùt hieän ñöôïc chöù khoâng chöùng minh ñöôïc chöông trình ñuùng vì khoâng theå thöû heát ñöôïc moïi tröôøng hôïp. Vì vaäy ngöôøi ta luoân coá gaéng chöùng minh chöông trình ñuùng cuûa chöông trình baèng logic song song vôùi chaïy thöû chöông trình. Coù 2 caùch chính thöôøng ñöôïc söû duïng ñeå ñaûm baûo tính ñuùng cuûa phaàn meàm trong quaù trình xaây döïng heä thoáng : - Vieát chöông trình roài chöùng minh chöông trình ñuùng. - Vöøa xaây döïng vöøa chöùng minh tính ñuùng cuûa heä thoáng. Vieäc tìm kieám nhöõng phöông phaùp xaây döïng toát ñeå coù theå vöøa xaây döïng vöøa kieåm chöùng ñöôïc tính ñuùng luoân laø moät chuû ñeà suy nghó cuûa nhöõng ngöôøi laäp trình . II. ÑAËC TAÛ 1. Ñaëc taû baøi toaùn a) Khaùi nieäm. Khi coù moät vaán ñeà ( moät baøi toaùn) caàn ñöôïc giaûi quyeát , ngöôøi ta phaùt bieåu baøi toaùn baèng moät vaên baûn goïi laø ñaëc taû baøi toaùn (problem specification). Caùc baøi toaùn ñaët ra cho nhöõng ngöôøi laøm coâng taùc tin hoïc thöôøng coù daïng sau : Xaây döïng moät heä thoáng xöû lyù thoâng tin maø hoaït ñoäng cuûa noù : - Döïa treân taäp döõ lieäu nhaäp (thoâng tin vaøo) thoaû maõn nhöõng ñieàu kieän nhaát ñònh. - Xaåy ra trong moät khung caûnh moâi tröôøng haïn cheá nhaát ñònh. - Mong muoán saûn sinh ra moät taäp döõ lieäu xuaát (thoâng tin ra ) ñöôïc quy ñònh tröôùc veà caáu truùc vaø coù moái quan heä vôùi döõ lieäu nhaäp vaø moâi tröôøng ñöôïc xaùc ñònh tröôùc . Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 54 - Nhöõng khía caïnh treân ñöôïc theå hieän trong ñaëc taû baøi toaùn (ÑTBT) . b) Taùc duïng cuûa ñaëc taû baøi toaùn . - Laø cô sôû ñeå ñaët vaán ñeà, ñeå truyeàn thoâng giöõa nhöõng ngöôøi ñaët baøi toaùn vaø nhöõng ngöôøi giaûi baøi toaùn . - Laø cô sôû ñeå nhöõng ngöôøi giaûi baøi toaùn trieån khai caùc giaûi phaùp cuûa mình . - Laø cô sôû ñeå nhöõng ngöôøi giaûi baøi toaùn kieåm chöùng tính ñuùng cuûa phaàn meàm taïo ra . - Laø phöông tieän ñeå nhieàu ngöôøi hieåu tính naêng cuûa heä thoáng tin hoïc maø khoâng caàn (thöôøng laø khoâng coù khaû naêng) ñi vaøo chi tieát cuûa heä thoáng . Ñeå ñaït ñöôïc 4 muïc tieâu treân, ÑTBT caàn goïn, roõ vaø chính xaùc . Ñeå ñaït ñöôïc muïc tieâu thöù 2, thöù 3 thì ngoân ngöõ ñeå vieát ÑTBT caàn phaûi coù tính hình thöùc (formal) vaø treân ngoân ngöõ naøy caàn coù caùc phöông tieän ñeå thöïc hieän caùc chöùng minh hình thöùc . Ngoân ngöõ thích hôïp vôùi yeâu caàu naøy laø ngoân ngöõ toaùn hoïc vaø heä logic thích hôïp laø logic toaùn hoïc. Ngöôøi ta thöôøng söû duïng ngoân ngöõ baäc nhaát (vôùi caùc khaùi nieäm vaø toaùn töû toaùn hoïc) vaø logic baäc nhaát . Tuyø theo möùc ñoä phöùc taïp cuûa baøi toaùn maø phöông tieän dieãn ñaït ÑTBT coù nhöõng möùc ñoä phöùc taïp vaø möùc ñoä hình thöùc khaùc nhau . ÔÛ möùc baøi toaùn lôùn, trong moái quan heä giöõa ngöôøi söû duïng vaø ngöôøi phaân tích, ngöôøi ta duøng : saùch hôïp ñoàng traùch nhieäm (cahier des charges), sô ñoà toå chöùc, bieåu ñoà luaân chuyeån thoâng tin Giöõa nhöõng ngöôøi phaân tích, ngöôøi ta duøng phieáu phaân tích caùc ñôn vò chöùc naêng, bieåu ñoà chöùc naêng Keát quaû phaân tích ñöôïc chuyeån thaønh yeâu caàu vôùi ngöôøi laäp trình baèng caùc ñaëc taû chöông trình (ÑTCT - program specification) . 2. Ñaëc taû chöông trình (ÑTCT). ÑTCT goàm caùc phaàn sau : - Döõ lieäu nhaäp : Caùc döõ kieän maø chöông trình söû duïng . Ñaëc tröng quan troïng laø danh saùch döõ lieäu nhaäp vaø caáu truùc cuûa chuùng , coù khi caàn neâu nguoàn goác , phöông tieän nhaäp cuûa moãi döõ lieäu nhaäp . - Ñieàu kieän raøng buoäc treân döõ lieäu nhaäp : laø nhöõng ñieàu kieän maø döõ lieäu nhaäp phaûi thoaû ñeå heä thoáng hoaït ñoäng ñuùng . Chöông trình khoâng baûo ñaûm cho keát quaû ñuùng khi thöïc thi caùc boä döõ lieäu khoâng thoaû caùc ñieàu kieän naøy . Trong phaàn moâ taû döõ kieän nhaäp caàn neâu leân : + Caáu truùc : kieåu döõ lieäu ( caùc thaønh phaàn, söï keát noái caùc thaønh phaàn ). + Caùc raøng buoäc treân gía trò cuûa chuùng . - Döõ lieäu xuaát : Caùc döõ lieäu maø chöông trình taïo ra . Cuõng nhö phaàn döõ lieäu nhaäp, caàn neâu roõ danh saùch döõ lieäu xuaát, caáu truùc cuûa chuùng, coù khi caàn neâu phöông tieän xuaát cuûa töøng döõ lieäu xuaát. Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 55 - - Ñieàu kieän raøng buoäc treân döõ lieäu xuaát: Nhöõng ñieàu kieän raøng buoäc maø döõ lieäu xuaát phaûi thoaû. Chuùng theå hieän yeâu caàu cuûa ngöôøi söû duïng ñoái vôùi chöông trình. Caùc ñieàu kieän naøy thöôøng lieân quan ñeán döõ lieäu nhaäp . Ví duï 1 : Vieát chöông trình ñoïc vaøo moät soá nguyeân döông N roài xuaát ra maøn hình N soá nguyeân toá ñaàu tieân. Ñaëc taû chöông trình : + Döõ lieäu nhaäp : moät soá nguyeân N . + Ñieàu kieän nhaäp : N > 0 , nhaäp vaøo töø baøn phím. + Döõ lieäu xuaát : moät daõy goàm N soá nguyeân . + Ñieàu kieän xuaát : laø daõy N soá nguyeân toá ñaàu tieân , xuaát ra maøm hình . Ví duï 2 : Vieát chöông trình ñoïc vaøo moät daõy N soá nguyeân , xuaát ra maøn hình daõy ñaõ saép xeáp theo thöù töï khoâng giaûm. Ñaëc taû chöông trình : + Döõ lieäu nhaäp : moät array A coù N phaàn töû laø soá nguyeân . + Ñieàu kieän nhaäp : nhaäp töø baøn phím . + Döõ lieäu xuaát : array A' coù N phaàn töû laø soá nguyeân. + Ñieàu kieän xuaát : xuaát ra maøn hình ,A' laø moät hoaùn vò cuûa A , A' laø moät daõy khoâng giaûm. ( 1 A'[i] <= A'[j] ) Chuù yù : Moät ñaëc taû toát cho moät ñònh höông ñuùng veà söû duïng hôïp lyù caùc caáu truùc döõ lieäu vaø moät gôïi yù toát veà höôùng xaây döïng giaûi thuaät cho baøi toaùn. 3. Ñaëc taû ñoaïn chöông trình . a) Khoâng gian traïng thaùi. Moät chöông trình söû duïng moät taäp caùc bieán xaùc ñònh. Moät bieán thuoäc moät kieåu döõ lieäu xaùc ñònh. Moät kieåu döõ lieäu xaùc ñònh moät taäp gía trò maø moãi bieán thuoäc kieåu coù theå nhaän . Taäp giaù trò maø bieán chöông trình X coù theå nhaän (mieàn xaùc ñònh cuûa bieán X ) goïi laø khoâng gian traïng thaùi (state space) cuûa bieán X . Xeùt chöông trình P giaû söû P söû duïng caùc bieán a , b , c ,. . . vôùi caùc khoâng gian traïng thaùi töông öùng laø : A , B , C , thì tích Decartes cuûa A,B,C, ( A ^ B ^ C ^ ) laø khoâng gian traïng thaùi cuûa chöông trình P . b) Ñaëc taû ñoaïn chöông trình. Xeùt moät tieán trình xöû lyù thöïc thi moät chöông trình . Moãi leänh cuûa chöông trình bieán ñoåi traïng thaùi caùc bieán cuûa chöông trình töø traïng thaùi naøy sang traïng thaùi khaùc , xuaát phaùt töø traïng thaùi ñaàu ( traïng thaùi khi baét ñaàu tieán trình xöû lyù) keát thuùc taïi traïng thaùi cuoái ( traïng thaùi khi tieán trình xöû lyù keát thuùc). Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 56 - ÔÛ töøng thôøi ñieåm tröôùc hoaëc sau khi thöïc hieän moät leänh , ngöôøi ta quan taâm ñeán taäp hôïp caùc traïng thaùi coù theå cuûa chöông trình. Taäp hôïp caùc traïng thaùi naøy seû ñöôïc bieåu thò bôûi caùc taân töø baäc nhaát vôùi caùc bieán laø caùc bieán cuûa chöông trình. Ví duï 1 : Ñoaïn chöông trình sau tính tích cuûa hai soá nguyeân döông a vaø b { ( a > 0) and (b > 0) } // raøng buoäc treân traïng thaùi ñaàu . x := a ; y := b ; u := 0 ; { ( x = a ) and (y = b ) and ( (u + x*y ) = (a*b) ) } // raøng buoäc trung gian treân repeat {(u+x*y = a*b) and ( y>0 ) } traïng thaùi cuûa CT. u := u + a ; y := y - 1 ; {(u+x*y = a*b) and (y >= 0) } // raøng buoäc trung gian treân traïng thaùi until (y= 0) cuûa chöông trình. {u= a*b} // raøng buoäc treân traïng thaùi xuaát Moãi taân töø trong ví duï treân moâ taû moät taäp caùc traïng thaùi coù theå coù ôû ñieåm ñoù. Ví duï 2 : Ñoaïn chöông trình hoaùn ñoåi noäi dung cuûa 2 bieán x vaø y, duøng bieán t laøm trung gian. {( x = xo) and (y = yo ) } // x , y mang giaù trò ban ñaàu baát kyø naøo ñoù t := x ; x := y ; y := t { (x = yo ) and (y = xo ) } // x , y sau cuøng mang giaù trò hoaùn ñoåi cuûa nhau. Trong ví duï naøy ñeå bieåu dieãn quan heä giöõa noäi dung caùc bieán vôùi noäi dung cuûa moät soá bieán bò gaùn trò, ngöôøi ta caàn phaûi duøng caùc bieán giaû (ghost variable). Ví duï ôû ñaây laø xo vaø yo bieåu thò noäi dung cuûa x vaø y tröôùc khi thöïc hieän ñoaïn chöông trình. Ví duï 3 : Nhaân 2 soá nguyeân döông x , y, keát quaû chöùa trong u . { (x = xo > 0) and (y = yo > 0 )} u := 0 ; repeat u := u + x ; y := y - 1 ; until (y = 0) { u = xo * yo } Thaät ra ôû ñaây taäp hôïp caùc traïng thaùi xuaát thöïc söï laø nhoû hôn, bieåu thò bôûi moät ñieàu kieän chaët hôn, ñoù laø : {( u = xo * yo ) and (y = 0) and (x = xo ) } Toång quaùt ta caàn khaûo saùt moät ñoaïn chöông trình S vôùi 2 ñieàu kieän ñi tröôùc P vaø ñi sau Q . Caàn chöùng minh raèng neáu xuaát phaùt töø traïng thaùi thoaû P thi haønh leänh S thì Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 57 - caàn ñaït tôùi traïng thaùi thoûa Q . P ñöôïc goïi laø ñieàu kieän ñaàu (precondition) , Q ñöôïc goïi laø ñieàu kieän cuoái (postcondition). Caëp taân töø (P,Q) , ñöôïc goïi ñaëc taû cuûa ñoaïn leänh S. Boä 3 S, P, Q taïo neân moät ñaëc taû ñoaïn leänh thöôøng ñöôïc moâ taû hình thöùc baèng taäp kyù hieäu : { P } S { Q } ( { P } : taäp traïng thaùi thoûa taân töø P , { Q } : taäp traïng thaùi thoûa taân töø Q ) Vieäc thieát laäp caùc khaúng ñònh ôû nhöõng ñieåm khaùc nhau trong chöông trình nhaèm ñeå : + Hoaëc laø ñaëc taû moät ñoaïn chöông trình caàn phaûi xaây döïng : tìm S thoûa P, Q cho tröôùc. + Hoaëc laø cô sôû ñeå chöùng minh tính ñuùng cuûa ñoaïn chöông trình S ( ñoaïn chöông trình S thoaû ñaëc taû ). + Hoaëc ñeå ñaëc taû ngöõ nghóa ñoaïn chöông trình (thöïc hieän söu lieäu chöông trình) nhaèm muïc ñích laøm ngöôøi ñoïc hieåu ñöôïc yù nghóa cuûa ñoaïn chöông trình III. NGOÂN NGÖÕ LAÄP TRÌNH. Ñeå kieåm chöùng tính ñuùng cuûa moät ñoaïn chöông trình, ñaàu tieân caàn trình baøy ñoaïn chöông trình ñoù trong moät daïng ngoân ngöõ laäp trình chuaån möïc ôû daïng coát loõi. Ngoân ngöõ laäp trình ôû daïng coát loõi chæ bao goàm caùc thao taùc chuaån : leänh gaùn, leänh ñieàu kieän, leänh laëp while vaø leänh gheùp (daõy tuaàn töï caùc leänh ). Cuù phaùp cuûa ngoân ngöõ coát loõi ñöôïc ñònh nghóa trong daïng BNF nhö sau : ::= | daõy leänh ::= | | ::= | ';' ::= | 'begin' 'end' ::= ':=' ::= 'if' 'then' 'else' | 'if' 'then' ::= 'while' 'do' Ñònh nghóa treân xaùc ñònh raèng moãi maø ta khaûo saùt coù theå laø : - : bao goàm caùc tröôøng hôïp : + Ví duï : Y := ( X + Y ) * Z ; + maø sau 'then' hay 'else' coù theå laø moät hay moät ñöôïc baét ñaàu bôûi 'begin' vaø chaám döùt bôûi 'end'. Ví duï : if (x > 0) then y := z else begin z := x * 2 ; if( z = y) then y := 0 end ; + vôùi moät bieåu thò ñieàu kieän laëp vaø Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 58 - Ví duï : while (x > 0) do begin y := x ; while ( y > 0) do y := y -1 ; x := x - 1 ; end ; - chính laø daõy tuaàn töï caùc ngaên caùch bôûi daáu ';' Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 59 - CHÖÔNG V KIEÅM CHÖÙNG TÍNH ÑUÙNG COÙ ÑIEÀU KIEÄN I. CAÙC KHAÙI NIEÄM VEÀ TÍNH ÑUÙNG. Xeùt boä 3 goàm : ñoïan leänh S, caùc taân töø treân caùc bieán cuûa chöông trình (coù theå bao goàm caùc bieán giaû) P, Q ( Pø moâ taû ñieàu kieän ñaàu , Q moâ taû ñieäu kieän cuoái ). Boä 3 : { P } S { Q } taïo neân ñaëc taû ñoaïn leänh S . Ñaëc taû : { P } S { Q } ñöôïc goïi laø thoûa ñaày ñuû ( ñuùng ñaày ñuû – ñ ñ ñ ) neáu xuaát phaùt töø baát kyø 1 traïng thaùi thoûa P thöïc hieän ñoaïn leänh S thì vieäc xöû lyù seû döøng ôû traïng thaùi thoûa Q . Ñaëc taû : { P } S { Q } ñöôïc goïi laø thoûa coù ñieàu kieän ( ñuùng coù ñieàu kieän – ñcñk ) neáu xuaát phaùt töø baát kyø 1 traïng thaùi thoûa P thöïc hieän ñoaïn leänh S neáu vieäc xöû lyù döøng thì traïng thaùi cuoái thoûa Q ( tính döøng cuûa S chöa ñöôïc khaúng ñònh ). Khaúng ñònh { P } S { Q } dieãn ñaït tính ñuùng coù ñieàu kieän (condition correctness) (tñcñk) cuûa S. Tính ñuùng cuûa S döïa treân ñkñ P vaø ñkc Q vôùi giaû ñònh raèng tính döøng cuûa S ñaõ coù. Ví duï : a) { (x = xo ) and (y = yo ) } Neáu (x = xo ) vaø (y = yo ) tröôùc khi t := x t := x ñöôïc thi haønh {( t = x = xo ) and (y = yo ) } Thì sau ñoù ( t = x = xo ) vaø (y = yo ) b) {( t = x = xo ) and (y = yo ) } Neáu (t = x = xo ) vaø ( y = yo) tröôùc khi x := y x := y ñöôïc thi haønh { (t = xo ) and (x = y = yo ) } Thì sau ñoù ( t = xo ) vaø ( x = y = yo ) c) { (t = xo ) and (x = y = yo ) } Neáu (t = xo ) vaø (x = y = yo ) tröôùc khi y := t y := t ñöôïc thi haønh {( y = xo ) and (x = yo ) } Thì sau ñoù ( y = xo ) vaø ( x = yo ) Caùc phaùt bieåu a, b, c laø ñuùng theo caûm nhaän cuûa ta veà leänh gaùn. d) { x > 0 } Neáu (x > xo ) tröôùc khi x := x-1 x := x-1 ñöôïc thöïc hieän { x > 0 } Thì sau ñoù ( x > 0 ) Phaùt bieåu d laø sai vì coù moät traïng thaùi ban ñaàu x = 1 thoaû P ( x > 0 ) nhöng sau khi thi haønh leänh x := x -1 (x giaûm 1) thì x = 0 khoâng thoaû Q ( x > 0 ) . II. HEÄ LUAÄT HOARE (HOARES INFERENCE RULES). Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 60 - Ñeå coù theå thöïc hieän chöùng minh hình thöùc veà tính ñuùng cuûa caùc ñoaïn chöông trình, ta caàn coù nhöõng tieàn ñeà moâ taû taùc ñoäng cuûa caùc thao taùc xöû lyù cô baûn (leänh cô baûn ) cuûa ngoân ngöõ duøng vieát chöông trình ( ôû ñaây laø ngoân ngöõ coát loõi ñaõ ñöôïc giôùi thieäu ô û IV.3 ). Moät heä tieân ñeà coù taùc duïng nhö theá cuûa Ca. Hoare , ñöôïc trình baøy döôùi daïng moät heä luaät suy dieãn (inference rules ) ñöôïc xeùt döôùi ñaây . 1. Caùc luaät heä quaû (Consequence rules) 1a. P => Q , { Q } S { R } –––––––––––––––– (1a) { P } S { R } Neáu ñkñ P maïnh hôn ñieàu kieän Q .Töùc laø: P ⇒ Q hay { P } ⊆ { Q } ( taäp hôïp caùc traïng thaùi thoaû P laø taäp con cuûa caùc taäp traïng thaùi thoaû Q ) vaø moãi traïng thaùi thoaû Q ñeàu ñaûm baûo traïng thaùi sau khi thi haønh S (vôùi giaû ñònh S döøng) thoaû R thì moãi traïng thaùi thoaû P ñeàu ñaûm baûo traïng thaùi sau khi thi haønh S (vôùi giaû ñònh S döøng) thoaû R. Ví duï 1 : Kieåm chöùng tñcñk ñaëc taû sau : { x = 3 } x := 5 ; y := 2 { x = 5, y = 2 } Ta coù : { true} x := 5 ; y := 2 { x = 5 ; y = 2 } (a) // taïm coâng nhaän vaø ( x = 3 ) => true (b) // hieån nhieân Neân { x = 3 } x := 5 ; y := 2 { x = 5, y = 2 } // theo tieân ñeà (1a) Ví duï 2 : Kieåm chöùng tñcñk ñaëc taû sau : { x > 3 } x := x -1 { x > 0 } Ta coù : { x > 1 } x := x-1 { x > 0 } (a) //taïm coâng nhaän vaø ( x > 3 ) => ( x > 1) (b) // hieån nhieân Neân { x > 3 } x := x -1 { x > 0 } // theo tieân ñeà (1a) 1b. Q => R , { P } S { Q } –––––––––––––––––– (1b) { P } S { R } Ví duï 3 : Kieåm chöùng tñcñk ñaëc taû sau : { true } x := 5 ; y := 2 { odd(x) and even(y) } Ta coù : { true } x := 5 ; y := 2 { (x = 5) , ( y = 2 ) } (a) // taïm coâng nhaän vaø ( (x = 5) and (y = 2)) => odd(x) and even(y) (b) // hieån nhieân Neân { true } x := 5 ; y := 2 { odd(x) and even(y) } //theo (1b) Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 61 - Ví duï 4 : Kieåm chöùng tñcñk ñaëc taû : { x > 1 } x := x -1 { x >= 1 } Ta coù : { x > 1 } x := x-1 { x > 0 } (a) // taïm coâng nhaän vaø ( x > 0 ) => ( x >= 1) // (b) // vì x laø bieán nguyeân Neân { x > 1 } x := x -1 { x >= 1 } // theo (1b) Hai luaät naøy cho pheùp lieân keát caùc tính chaát phaùt sinh töø caáu truùc chöông trình vôùi caùc suy dieãn logic treân döõ kieän. 2. Tieân ñeà gaùn (The Assignement Axiom) { P(bt) } x := bt { P(x) } (2) Töø (2 ) ta suy ra neáu tröôùc leänh gaùn x := bt ; traïng thaùi chöông trình laøm P(bt) sai (thoaû not P(bt) ) thì sau leänh gaùn P(x) cuõng sai (thoûa notP(x)). Leänh gaùn x := bt xoaù giaù trò cuõ cuûa x , sau leänh gaùn x mang giaù trò môùi laø trò cuûa bieåu thöùc bt , coøn taát caû caùc bieán khaùc vaãn giöõ giaù trò nhö cuõ. Ví duï : Tính ñuùng coù ñieàu kieän cuûa caùc ñaëc taû sau ñöôïc khaúng ñònh döïa vaøo tieân ñeà gaùn a) { x = x } y := x { x = y } b) { 0 <= s + t - 1 } s := s + t - 1 { 0 <= s } c) { i = 10 } j := 25 { i = 10 } 3. Caùc luaät veà caùc caáu truùc ñieàu khieån . a) Luaät veà daõy leänh tuaàn töï ( Rules on Sequential Composition ) { P } S1 { R } , { R } S2 {Q } –––––––––––––––––––––– (3.1) { P } S1 ; S2 { Q } Giaû ñònh coù tính döøng cuûa S1 vaø S2, luaät naøy phaùt bieåu yù sau : Neáu: i) Thi haønh S1 vôùi ñkñ P ñaûm baûo ñkc R ( ñaëc taû { P } S1 { R } ñ cñ k ) ii) Thi haønh S2 vôùi ñkñ R ñaûm baûo ñkc Q ( ñaëc taû { R } S2 { Q } ñ cñ k) Thì : thi haønh S ≡ S1 ; S2 vôùi ñkñ P ñaûm baûo ñkc Q (ñ aëc taû { P } S1 ; S2 { Q } ñ cñ k ) Ví duï : Kieåm chöùng tñcñk ñaëc taû : Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 62 - {true} x := 5 ; y := 2 { x = 5, y = 2 } Ta coù : { 5 = 5 } x := 5 { x= 5} (a) // tieân ñeà gaùn true =>( 5 = 5 ) vaø ( x = 5) => ( (x = 5) and (2 = 2) ) (b) // hieån nhieân {true} x := 5 {( x = 5) and ( 2 = 2) } (c) //theo luaät heä quûa { x = 5 , 2 = 2 } y := 2 {( x = 5) and ( y = 2) } (d) // tieàn ñeà gaùn {true} x := 5 ; y := 2 { x = 5, y = 2 } // theo luaät tuaàn töï b) Luaät veà ñieàu kieän (choïn) (Rule for conditionals) b1) { P and B} S1 {Q }, { P and (not B)} S2 { Q } ––––––––––––––––––––––––––––––––––––– (3.2a) { P } if B then S1 else S2 { Q } YÙ nghóa luaät naøy laø : Neáu coù : { P and B } + Neáu xuaát phaùt töø traïng thaùi thoûa P and B S1 thi haønh S1 thì seû tôùi traïng thaùi thoûa Q { Q } Vaø { P and notB } + Neáu xuaát phaùt töø traïng thaùi thoûa P and not B S2 thi haønh S2 thì seû tôùi traïng thaùi thoûa Q { Q } Thì suy ra : { P } Neáu xuaát phaùt töø traïng thaùi thoûa P if B then S1 else S2 thi haønh leänh if B then S1 else S2 { Q } thì seõ tôùi traïng thaùi thoûa Q . b2) { P and B} S { Q} , P and (not B ) => Q –––––––––––––––––––––––––––––––––––– (3.2b) { P } if B then S { Q} Ví duï1 : Kieåm chöùng tñcñk ñaëc taû : { i> 0 } if ( i= 0 ) then j := 0 else j := 1 {j=1} Ta coù : ((i> 0) and (i = 0)) ≡ false (a) //hieån nhieân { (i> 0 ) and (i = 0)} j := 0 {j=1} (b) //{false} S { Q } ñuùng vôùi ∀ S , Q ( (i> 0) and not(i = 0)) ≡ true (c) // hieån nhieân Traàn Hoaøng Thoï Khoa Toaùn - Tin
- Kyõ thuaät laäp trình naâng cao - 63 - {true } j := 1 { j=1 } (d) //tieân ñeà gaùn {(i >0) and not(i = 0)} j := 1 {j=1} (e) // c,d ,luaät heä quûa Töø b ,e vaø tieân ñeà 3.2a ta suy ra ÑPCM. Ví duï2 : Kieåm chöùng tñcñk ñaëc taû : {i >= j - 1} if ( i > j) then j := j+1 else i := i+1 {i >= j} Ta coù : {i >= j+1} j := j+1 {i >= j} (a) //tieân ñeà gaùn ((i >= j-1) and (i > j)) ==> (i >= j+1) (b) // bieán ñoåi vôùi chuù yù i , j nguyeân {(i >= j-1) and (i > j)} j := j + 1 {i >= j} (c) // a,b ,luaät heä quaû {i+1 >= j} i := i+1 {i >= j} (d) // tieân ñeà gaùn ((i >= j-1) and not(i > j)) ==> (i+1 >= j) (e) // bieán ñoåi {(i >= j-1) and not(i > j)} i := i + 1 {i >= j} (g) // d ,e , luaät heä quaû) Töø c , g döïa vaøo 3.2a suy ra ÑPCM. Ví du ï3 : Kieåm chöùng tñcñk ñaëc taû : {true} if odd(x) then x := x+1 {even(x)} Ta coù : {even(x+1)} x := x+1 {even(x)} (a) //tieân ñeà gaùn true and odd(x) ==> even(x+1) (b) // hieån nhieân {true and odd(x)} x := x+1 {even(x)} (c) // a ,b , luaät heä quaû true and not odd(x) ==> even(x) (d) // hieån nhieân Töø (c) vaø (d) döïa vaøo 3.2b suy ra ÑPCM . b3) Luaät veà leänh laëp While { I and B } S { I } ––––––––––––––––––––––––– (3.3) { I } while B do S { I and (not B ) } Luaät naøy noùi raèng neáu I khoâng bò thay ñoåi bôûi moät laàn thöïc hieän leänh S thì noù cuõng khoâng bò thay ñoåi bôûi toaøn boä leänh laëp While B do S. Vôùi yù nghóa naøy I ñöôïc goïi laø baát bieán (invariant) cuûa voøng laëp. Chuù yù raèng khaúng ñònh : { P } while B do S { Q } thoûa döïa vaøo heä luaät Hoare chæ xaùc ñònh tñcñk (conditionnal correctness). Ñeå chöùng minh tính ñuùng (correctness) thöïc söï ta caàn boå sung chöùng minh leänh laëp döøng. Ví duï1 : Kieåm chöùng tính ñuùng coù ñieàu kieän cuûa ñaëc taû : {i<=n} while (i < n ) do i := i+1 {i=n} Xem I laø ( i <= n ) thì : { I and ( i < n )} i := i+1 {I} (a) // deã kieåm chöùng Neân {I} while ( i < n ) do i := i+1 { I and not(i<n)} (b) // luaät 3.3 Traàn Hoaøng Thoï Khoa Toaùn - Tin