Bài toán sp xp dãy viên bi ba màu

Một phần của tài liệu Tài liệu Kiểu dữ liệu phức hợp_chương 3 doc (Trang 43)

Bài toán s p x p dãy các viên bi ba màu, hay còn đ c g i là bài toán c ba màu (drapeau français) đ c phát bi u nh sau : Cho tr c m t dãy các viên bi đánh s t 1 đ n N, m i viên bi mang m t màu ho c xanh, ho c tr ng, ho c đ . C n s p x p l i các viên bi theo th t

l n l t xanh, đ n tr ng, r i đ n đ sao cho ch đ c hoán v (đ i ch các viên bi) ngay trên dãy đã cho, h n n a, các hoán v ph i càng ít càng t t.

gi i bài toán này, ta đ a vào các v t B (blue), W (white) và R (red) v i quy c B(i), W(i) và R(i) là đúng n u và ch n u viên bi th i (1 i N) là xanh, tr ng và đ t ng ng. Ta c ng s d ng th t c hoán v permute(i, j) đ đ t viên bi th i thành j, viên bi th j thành i,

i, j1..N, không lo i tr tr ng h p i = j. 1 b w r N ↓ ↓ ↓ ↓ ↓ B W X R bi xanh bi tr ng ←⎯⎯→ bi đ Vùng ch a x lý

Hình III.12. Bài toán s p x p dãy các viên bi ba màu.

S d ng 3 ch s b, wrđ phân cách 4 vùng c a m ng (xem hình), thu t toán s p x p các vi n bi là x lý vùng ch a đ c s p x p X :

w:= 1; b := 1; r := n;

while w <= r do

if W(w) then w:= w+1 elsif B(w) then begin

permute(b, w); b:= b+1; w:= w+1

end else begin while (R(r) and w < r) then r:= r-1;

permute(r, w); r:= r-1

end

Th t c Scheme s p x p dãy các viên bi ba màu s d ng phép l p : (define (threecolor L)

(define (blue? x) (if (equal? 'b x) #t #f)) (define (white? x) (if (equal? 'w x) #t #f)) (define (red? x) (if (equal? 'r x) #t #f)) (define (threecolor_itr L b w r) (if (null? L) (append b w r) (let ((x (car L)) (y (cdr L))) (cond ((blue? x) (threecolor_itr y (cons x b) w r)) ((white? x) (threecolor_itr y b (cons x w) r)) (else (threecolor_itr y b w (cons x r))))))) (threecolor_itr L '() '() '())) (threecolor '(b w w r b r b r w w r b b w)) --> '(b b b b b w w w w w r r r r) 5. S p x p nhanh quicksort

Trong ch ng 1, ta đã xây d ng thu t toán quicksort s p x p nhanh các ph n t c a m t danh sách theo th t không gi m vi t b ng Miranda. Sau đây ta s minh ho b ng Scheme.

u tiên, ta xây d ng hàm phân chia partition cho phép chuy n m t danh sách thành m t danh sách khác (theo th t ng c l i) mà ph n t đ u c a nó là danh sách con ch a các giá tr nh h n ho c b ng ph n t tr c pivot đã cho, danh sách con còn l i ch a các giá tr l n h n ph n t tr c. Hàm có s d ng hai danh sách «m i» lúc đ u c hai đ u r ng.

(define (partition L pivot Linf Lsup) (cond ((null? L) (cons Linf Lsup))

((< (car L) pivot) (partition

(cdr L) pivot (cons (car L) Linf) Lsup)) (else (partition

(cdr L) pivot Linf (cons (car L) Lsup))))) (partition ’(6 4 7 8 5 9 2 3) 7 ’() ’())

--> ’((3 2 5 4 6) 9 8 7)

Bây gi xây d ng hàm quicksort g i đ quy vi c ch n ph n t tr c là ph n t đ u danh sách đ áp d ng hàm phân chia, các danh sách k t qu và ph n t tr c đ c ráp l i v i nhau và tr v k t qu là danh sách đã đ c s p x p.

(define (quicksort L)

(if (or (null? L) (null? (cdr L))) L

(let* ((pivot (car L)) (L1-L2

(partition (cdr L) pivot ’() ’())) (L1 (car L1-L2))

(L2 (cdr L1-L2))) (append (quicksort L1)

(cons pivot (quicksort L2)))))) (quicksort ’(7 6 4 7 8 5 9 2 3)) --> ’(2 3 4 5 6 7 7 8 9) Tóm t t ch ng 3 • • •

Ki u d li u ph c h p trong Scheme g m ki u chu i, ki u vect , ki u b đôi, ki u danh sách, ki u d li u th t c và ki u d li u c ng.

T t c các ki u d li u c a Scheme đ u đ c g i là ki u s-bi u th c. Có t t c 9 ki u d li u đ c g i là đ i t ng c a Scheme : (adsbygoogle = window.adsbygoogle || []).push({});

Tên ki u Ví d V t ki m tra ki u

S 9 number?

Ký t #\a ou #\space char?

Lôgic #t ho c #f boolean?

Ký hi u ’chip symbol?

B đôi ( 5 . 7 ) pair? Chu i "Tom and Jerry" string? Vect #( 5 3 12 ”Mickey” 32 ) vector?

Th t c --- procedure?

• • • • • •

Trong Scheme c ng nh trong ngôn ng l p trình h ng đ i t ng, ng i ta có th s d ng ki u d li u tr u t ng đ đnh ngh a các c u trúc d li u ph c t p.

M t ki u d li u tr u t ng g m 4 thành ph n : tên ki u, các đnh ngh a hàm, các đi u ki n đ u n u có và các tiên đ . Hai thành ph n đ u mô t cú pháp v m t c u trúc thu c tính c a ki u d li u tr u t ng, hai thành ph n sau mô t ng ngh a.

Scheme s d ng ki u d li u b đôi t ng t b n ghi g m m t c p ph n t nào đó có th t . Ph n t th nh t đ c g i là car, ph n t th hai cdr.Có m t d u ch m đ

phân cách hai giá tr ph n t .

Ki u d li u b đôi đ c s d ng đ xây d ng ki u danh sách : m t danh sách ho c có th r ng, ho c có th là m t b đôi có cdr l i là m t b đôi khác. Các thành ph n c a m t b đôi c ng có th là các b đôi.

Ki u danh sách đ c s d ng ph bi n trong Scheme. M t danh sách đ c xem là m t c u trúc g m hai thành ph n : ph n t đ u và ph n danh sách còn l i.

Khi x lý m t danh sách, ng i ta x lý ph n t đ u, sau đó s d ng phép đ quy đ

x lý ph n danh sách còn l i.

Bài t p ch ng 3

1. Gi i thích các bi u th c sau đây, sau đó tính giá tr và so sánh k t qu :

(cons 1 2)

(car (cons (cons 1 2) (cons 3 4))) (cons (cons (cons (cons 1 2) 3) 4) 5)

(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 ()))))) (list 1 2 3 4 5) (car (list 1 2 3 4 5)) (cdr (list 1 2 3 4 5)) (cadr (list 1 2 3 4 5)) (caddr (list 1 2 3 4 5)) 2. Vi t hàm t o các danh sách sau : (a b c d) (a ((b c) d (e f))) (a (b (c d) . e) (f g) . h)

3. Cho bi t nh ng bi u th c nào có cùng k t qu trong s các bi u th c sau đây : (list 1 ’(2 3 4)) (append ’(1) ’(2 3 4)) (list 1 2 3 4) (cons ’1 ’(2 3 4)) (cons ’(1) ’(2 3 4)) (cons ’1 ’((2 3 4))) (append ’(1) ’((2 3 4))) 4. Cho bi t giá tr c a các bi u th c sau :

’(+ 4 7) ’(a b)

(cdr ’(a)) (cdr week-list) (car ’((+ 4 1))) (cdr ’((+ 4 1))) (cdr ’((a) b)) (cdr ’((a) (b))) (cdr ’’(a b))

5. Cho bi t các danh sách t ng ng v i các s đ sau :

1) 2) a b

d e

a b c d e f

c

6. T hàm member, hãy đnh ngh a v t member?. (adsbygoogle = window.adsbygoogle || []).push({});

7. nh ngh a m t hàm đ phá h t các ngo c trong m t danh sách.

Ch ng h n, đ i v i danh sách ((a b c) (d (e f) g) h (i j)) thì hàm tr v : (a b c d e f g h i j)

8. Hàm concat sau đây dùng đ ghép hai danh sách t ng t append : (define (concat list1 list2)

(define (iter response remaining) (if (null? remaining)

(reverse response)

(iter (cons (car remaining) response) (cdr remaining))))

(iter list2 list1))

Tuy nhiên hàm không tr v k t qu đúng, hãy vi t l i cho phù h p, sao cho :

(concat ’(1 2 3 4 5) ’(6 7 8 9))

--> ’(1 2 3 4 5 6 7 8 9)

9. Vi t bi u th c trích danh sách đ tr v k t qu là danh sách con ’(sat, sun) : ’(mon tue wed thu fri sat sun).

10.Vi t các hàm tr v ph n t th hai, th ba và th t c a m t danh sách.

11.Vi t d ng t h p c a car và cdr đ nh n đ c giá tr là ký hi u a t các danh sách : ((b a) (c d)), (() (a d)), (((a)))

12.Cho bi t giá tr c a (car ’’a) và (cdr ’’a) (chú ý hai d u quote). 13.Vi t đnh ngh a t ng t đnh ngh a c a ki u list cho ki u plate-list.

14.Vi t hàm (count s L) đ m s l ng ký hi u s là ch cái xu t hi n trong danh sách ch cái L. Ví d :

(count ’R ’(T O M A N D J E R R Y)) --> 2

15.Vi t hàm (double L) nh n vào m t danh sách các ký hi u L đ tr v danh sách mà các ký hi u đã đ c vi t l p l i. Ví d :

(double ’(TOM AND JERRY))

--> ’(TOM TOM AND AND JERRY JERRY)

16.Vi t hàm (undouble L) nh n vào m t danh sách các ký hi u L trong đó các ký hi u

đ u b vi t l p l i đ tr v danh sách ch ch a m i ký hi u m t l n. Ví d : (undouble (double ’(TOM AND JERRY)))

--> ’(TOM AND JERRY)

17.T ví d x lý hình ch nh t trình bày trong lý thuy t, vi t v t disjoint? tr v #t n u hai hình ch nh t r i nhau, ngh a là không có đi m nào chung.

18.Xây d ng các hàm x lý hình ch nh t s d ng bi u di n các thành ph n b i danh sách. 19.Cho bi t giá tr các bi u th c d ng quasiquode sau đây :

`(1 + 2 = ,(+ 1 2))

`(the car of the list (a b) is ,(car ’(a b))) `(cons ,(+ 2 5) ,(list ’a ’b))

(let ((L ’(1 2 3)))

`((+ ,@L) = ,(+ 1 2 3)))

20.Dùng ki u b đôi (pair-doublet) đ bi u di n s ph c (a + bi). Hãy tính c ng, nhân và lu th a b c n nguyên d ng c a m t s ph c. Cho bi t :

C ng: (a + bi) ± (c + di) = (a ± c) + (b ± d)i (adsbygoogle = window.adsbygoogle || []).push({});

Tr : (a + bi) − (c + di) = (a − c) + (b − d)i

Nhân : (a + bi) × (c + di) = (ac − bd) + (ad ± bc)i

Chia : −

2 2 2 2

(a + bi) (ac + bd) (bc ad)

= + i

(c + di) (c + d ) (c + d ) , v i đi u ki n c2 + d2≠ 0. Lu th a : (a + bi)n = rn(cosnϕ + isinnϕ), trong đó :

r = a + b2 2 , ϕ = arctgb a C n b c hai : a + bi = x + yi , trong đó : ⎛ ⎞ ⎛ ⎞ ⎛ ⎞ ⎛ ⎞ + ⎜ ⎟ ⎜ ⎟ = − + ⎜ ⎟ ⎜ ⎟ ⎝ ⎠ ⎝ ⎠ ⎝ ⎠ ⎝ ⎠ 2 2 2 2 a a b a a b x = + , y + 2 2 2 2 2 2 N u a > 0, tính x và lúc đó, y = b x 2 , n u a < 0, tính y và lúc đó, x = b y 2 .

CH NG IV. K THU T X LÝ HÀM

h ng này s trình bày chi ti t h n m t s k thu t s d ng và x lý hàm nh : dùng tên hàm làm tham đ i, dùng hàm làm giá tr tr v c a m t hàm khác, đnh ngh a hàm nh phép tính lambda, tham đ i hoá t ng ph n, k thu t l p trình nh trao đ i thông đi p gi a các hàm, k thu t đ quy c c b , ph ng pháp t h p các hàm, đnh ngh a các hàm có s l ng tham đ i b t k , v.v…

C

IV.1 S d ng hàm

Cho đ n lúc này, ta đã s d ng defineđ đnh ngh a bi n và hàm Scheme nh sau :

(define v s)

trong đó : v (variable) là m t bi n

s là m t bi u th c

(define (f L) s)

trong đó : L dãy t 0.. n bi n,

f là tên hàm hay tên bi n,

s là bi u th c đóng vai trò thân c a hàm

M t hàm trong Scheme đ c xem nh m t ki u d li u hay m t s-bi u th c, do đó, hàm có th đ c dùng làm tham đ i và c ng có th làm giá tr tr v . Ta s xét l n l t hai kh n ng này và m t cách khác đnh ngh a hàm nh phép tính lambda (λ-calculus).

IV.1.1.Dùng tên hàm làm tham đ i

Gi s ta đnh ngh a m t hàm tu ý nh sau : (define (f x) (list x x)) (f ’a)

--> ’(a a)

Bây gi ta đnh ngh a hàm g qua f nh sau : (define g f)

N u ta g i hàm g nh là m t bi n thì s gây ra l i sai :

g

--> ERROR: ’#{Procedure 6703 f} (báo l i trong Scheme48) Hàm g ph i đ c g i t ng t hàm fđ có cùng k t qu :

(g ’a) --> ’(a a)

Gi s ta đnh ngh a l i hàm car b i m t tên khác nh sau : (define first car) (adsbygoogle = window.adsbygoogle || []).push({});

first

--> ERROR:#<primitive-procedure car> ; sai vì first là hàm, không ph i bi n

(first (list 1 2 3)) --> 1 Nh v y, n u m t hàm có m t tham đ i f1 nào đó đã đ c đnh ngh a tr c đó, thì m i đnh ngh a d ng : (define (f2 x) (f1 x)) đ u có th vi t ng n g n thành : (define f2 f1)

Ta có th m r ng cho các hàm nhi u tham đ i : (define (g2 x y z) (g1 x y z)) (define (g1 x y z) (+ x y z)) (procedure? g2) ; g2 là m t hàm --> #t (g2 (+ 1 2) 4 5) --> 12 Trong ki u d li u tr u t ng, hai l i g i th c hi n (* 2 2) và (* 3 3) c a d ng hàm nhân (* num num) có ngu n g c t khai báo hàm :

* : number × number → number

đ t đó ta có đnh ngh a hàm square : (define (square x) (* x x))

Gi s ta c n xây d ng hàm sum-integer tính t ng các s nguyên và hàm sum- square tính t ng các bình ph ng các s nguyên gi a hai s nguyên a và b đã cho. Ta có :

; Integer × Integer → Integer (define (sum-integer a b)

(if (> a b) 0

(+ a (sum-integer (+ a 1) b))) ; Integer × Integer → Integer

(define (sum-square a b) (if (> a b)

0

C hai hàm trên đ u có cùng m t «giu c» là : (define (sum-any a b)

(if (> a b) 0

(+ (func a) (sum-any (+ a 1) b))))

Ta có th xem hàm sum-any s d ng func nh là tham đ i hình th c c a hàm. T đó ta có th đnh ngh a l i hàm này nh ng có 3 tham đ i nh sau :

(define (sum-any func a b)

;(Integer→Integer)×Integer ×Integer→Integer (if (> a b)

0

(+ (func a) (sum-any func (+ a 1) b)))) (sum-any square 9 16)

--> 1292

(sum-any sqrt 16 25) --> 45.1646

Do func là m t hàm b t k nên ta có th m r ng hàm sum-any đ th c hi n phép c ng các s th c, có d ng t ng quát h n nh sau :

(number → number) × integer × integer → number (sum-any sqrt 1.2 4.5) ; tính t ng các c n b c hai các s nguyên --> 6.41693

Hàm sum-any cho phép đnh ngh a các hàm riêng bi t b ng cách thêm m t đnh ngh a hàm th c hi n ch c n ng c a func đ không s d ng func nh là tham đ i n a :

(define (sum-square a b)

(define (square x) (* x x)) ; đnh ngh a hàm func= square (sum-any square a b))

(sum-square 4 9) --> 271

(define (sum-integer a b)

(define (id x) x) ; đnh ngh a hàm func= id (sum-any id a b)) (sum-integer 4 9) --> 39 (define (sum-sqrt a b) (sum-any sqrt a b)) (sum-sqrt 4 9) --> 15.1597 (sum-any sqrt 4 9) --> 15.1597 (adsbygoogle = window.adsbygoogle || []).push({});

Sau đây là m t ví d khác s d ng k thu t dùng tên hàm làm tham đ i. Gi s ta c n tính

đ o hàm f ’ c a m t hàm f t i m t đi m x theo công th c : 0 ( ) - ( ) '( ) lim dx f x dx f x f x dx → + =

S gia dx ph i t ng đ i nh sao cho c l ng là đúng. Hàm tính đ o hàm đ c đnh ngh a nh sau :

; derivative:(number→number)=number×number→number (define (derivative f x dx)

(/ (- (f (+ x dx)) (f x)) dx))

Trong đnh ngh a hàm derivative, ta đã s d ng tên hàm đ tính toán m t cách hình th c, ch khi có l i g i, tên hàm m i đ c nh n hàm c th . Tên hàm xu t hi n nh là m t trong 3 tham đ i : (derivative sqrt 5 .00001) --> 0.223607 (define (cube x) (* x x x)) (derivative cube 5 .00001) --> 75.0001

IV.1.2.Áp d ng hàm cho các ph n t c a danh sách

Gi s c n xây d ng hàm có các tham đ i là k t qu áp d ng m t hàm f nào đó lên các ph n t xi c a danh sách : (x1, ... , xn) đ tr v giá tr là m t danh sách : (f(x1) ... f(xn)) ta có th đnh ngh a hàm mapto nh sau : (define (mapto f L) (if (null? L) ’() (cons (f (car L)) (mapto f (cdr L))))) (mapto odd? ’(4 1 8 5 0 -5 )) −−> ’(#f #t #f #t #f #t)

Th vi n Scheme có các hàm map, for-each, apply nh n tham đ i là k t qu áp d ng m t hàm nào đó cho các ph n t c a danh sách.

Cú pháp hàm mapnh sau :

; map:(T1×T2×...×Tn→ T)×List(T1)×...×List(Tn)→List(T) (map f L1 L2 ... )

Hàm mapđ a ra l i g i áp d ng m t hàm f, hay m t phép toán, cho m i ph n t l n l t là danh sách L1, L2, ... , sau đó tr v m t danh sách c a t t c các k t qu . Ví d :

(map cadr ’((a b) (d e) (g h))) --> (b e h)

(map square (list 1 2 3 4)) ; square tính bình ph ng m t s --> (1 4 9 16)

(map list (list 1 2 3 4)) --> ((1) (2) (3) (4))

(map + (list 1 2 3 4) (list 4 5 6)) --> (5 7 9)

(map append (list) (list)) --> ‘()

(map cons ’(1 2 3) ’(10 20 30)) --> ((1 . 10) (2 . 20) (3 . 30)) (map + '(1 2 3) '(10 20 30)) --> (11 22 33)

Chú ý r ng m t s d ng đ c bi t không th s d ng nh hàm đ làm tham đ i f c a map, ch ng h n :

(map or ’(#f #t #f) ’(#t #f #t)) --> ERROR

Mu n s d ng nh ng d ng đ c bi t nh v y c n s d ng bi u th c lambda (s xét trong m c ti p theo) :

(map (lambda (x y) (or x y))

’(#f #t #f) ’(#t #f #f)) --> ’(#t #t #f)

Cú pháp c a for-eachnh sau : (for-each f L1 L2 ... )

Hàm for-each th c hi n t ng t map, áp d ng hàm f l n l t cho m i ph n t trong các danh sách nh ng ch khi x y ra hi u ng ph (side-effects).

(for-each display

(list ”one ” ”two ” ”buckle my shoe”)) --> one two buckle my shoe

Cú pháp hàm apply : (apply f L1 L2 ... )

Hàm apply c a Scheme cho phép áp d ng m t hàm cho m t danh sách các tham đ i (chú ý tham đ i đ u tiên ph i đ c vi t tách riêng) :

(apply + ’(2 3 5)) --> 10 (apply * 2 ’(3 5)) --> 30 (apply * ’(2 3 5)) --> 30 (adsbygoogle = window.adsbygoogle || []).push({});

S d ng th t c l p map có th tác đ ng xu ng các m c sâu h n c a m t danh sách. Ch ng h n ta c n tính đ sâu c a m t s-bi u th c có d ng danh sách, ta xây d ng hàm depth ho t đ ng nh sau : n u danh sách khác r ng, c ng 1 vào đ sâu t i đa c a m i ph n t c a danh sách.

(define (depth s)

(cond ; ki u nguyên t có đ sâu 0 ((atom? s) 0)

; danh sách ph ng có đ sâu 1 ((null? s) 1)

(else (+ 1

(apply max (map depth s)))))) (depth ’a)

−−> 0

(depth ’(a))

−−> 1

(depth ’(a (b c) ((d (e))) ”yes” ()))

−−> 4

IV.1.3.K t qu tr v là hàm

Trong Scheme, hàm có th đ c dùng nh giá tr k t qu tr v c a m t hàm khác. Ch ng h n hàm tính đ o hàm f ’ c a m t hàm f nào đó v a đ c đnh ngh a trên đây đ c s a l i ch còn 2 tham đ i, g m tên hàm c n tính đ o hàm f và s gia dx. Sau khi th c hi n, hàm tr v m t hàm khác đ ch tham đ i th ba, là x :

Một phần của tài liệu Tài liệu Kiểu dữ liệu phức hợp_chương 3 doc (Trang 43)