Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 90 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
90
Dung lượng
1,11 MB
Nội dung
CHNG III. KIU D LIU PHC HP If worms have the power of acquiring some notion, however rude, of the shape of an object and of their burrows, as seems to be the case, they deserve to be called intelligent. Charle R. Darwin (Vegetable Mould, 1881) iu d liu phc hp trong Scheme gm kiu chui (string), kiu vect (vector), kiu b đôi (doublet), kiu danh sách. Ngoài ra, Scheme còn mt s kiu d liu phc hp khác. Kiu d liu th tc (procedure) ch đnh các bin cha giá tr tr v ca hàm. Kiu d liu cng (port) ch đnh các cng vào-ra tng ng vi các tp và các thit b vào-ra (bàn phím, màn hình). Cui cùng, tt c các kiu d liu va xét trên đây, k c kiu đn gin, đu đc Scheme gom li thành mt giuc đc gi là kiu s-biu thc. K Sau đây, ta s ln lt trình bày các kiu d liu chui, vect, b đôi và danh sách. Trong phn trình bày kiu d liu b đôi, chúng ta s nghiên cu khái nim tru tng hoá d liu (data abstraction). III.1 Kiu chui Chui là mt dãy các ký t bt k đc vit gia mt cp du nháy đôi (double-quotes). Giá tr ca chui chính là bn thân nó. Ví d sau đây là mt chui : ”Cha`o ba.n !” --> ”Cha`o ba.n !” Có th đa vào trong chui du nháy đôi, hay du \ (reverse solidus), bng cách đt mt du \ phía trc, chng hn : (display ”two \”quotes\” within.”) --> two ”quotes” within. Th vin Scheme có hàm string cho phép ghép liên tip các ký t thành mt chui : (string #\S #\c #\h #\e #\m #\e) --> ”Scheme” Ta có th đnh ngha mt bin nhn giá tr kiu chui : (define greeting ”Scheme ; cha`o ba.n !”) ; Chú ý du ; trong mt chui không có vai trò là du chú thích. tip cn đn mt ký t ca chui mt v trí bt k, cn s dng hàm string-ref. Ch s ch v trí ký t là mt s nguyên dng, tính t 0. Ch s hp l ln nht ca chui đã cho là chiu dài ca chui tr đi 1 : (string-length greeting) --> 21 61 62 LP TRÌNH HÀM (string-ref greeting 0) --> #\S (string-ref greeting 20) --> #\! (define Str ; s dng hàm ghép liên tip các chui (string-append ”Chuoi \”” greeting ” \” co do dai 21.”)) (display Str) --> Chuoi ”Scheme ; cha`o ba.n ! ” co do dai 21. V t string? dùng đ kim tra kiu chui : (string? greeting) --> #t S dng hàm make-string, ta có th to ra mt chui có đ dài bt k và cha các ký t bt k : (define a-5-long-string (make-string 5)) a-5-long-string --> ”?????” (define a-5-asterisk-string (make-string 5 #\*)) a-5-asterisk-string --> ”*****” Hàm string-set! dùng đ thay th mt ký t trong chui đã cho ti mt v trí bt k cho bi ch s : (string-set! a-5-long-string 0 #\c) a-5-long-string --> ”c????” Trên đây ta đã s dng các hàm x lý chui : (string? Str) Tr v #t nu str là mt chui, nu không tr v #f. (string-append str 1 str 2 .) Tr v chui ghép liên tip các chui str 1 , str 2 . (make-string k [char]) Tr v mt chui mi có đ dài k. Nu có tham bin char, thì tt c các ký t ca chui s là char, nu không ni dung ca chui s không đc xác đnh. (string-length str) Tr v đ dài ca chui str. (string-ref str k) Tr v ký t th k ca chui str. Giá tr ca k phi hp l. (string-set! string k char) t giá tr ký t th k ca chui str bi char. Giá tr ca k phi hp l. Sau đây là mt s hàm x lý chui khác ca Scheme : Các v t so sánh chui : (string=? str 1 str 2 ) KIU D LIU PHC HP 63 (string<? str 1 str 2 ) (string>? str 1 str 2 ) (string<=? str 1 str 2 ) (string>=? str 1 str 2 ) tr v #t nu tha mãn quan h th t t vng =, <, >, <=, >= gia các chui (có phân bit ch hoa ch thng), tr v #f nu không tha mãn. Phép so sánh da trên các v t so sánh ký t char=?, char<?, char>?, char<=?, và char>=?. Hai chui đc xem nh tng đng v mt t vng nu chúng có cùng chiu dài và bao gm dãy các ký t ging nhau tng ng vi char=?. Các v t sau đây cng cho kt qu tng t nhng phép so sánh chui không phân bit ch hoa ch thng : (string-ci=? str 1 str 2 ) (string-ci<? str 1 str 2 ) (string-ci>? str 1 str 2 ) (string-ci<=? str 1 str 2 ) (string-ci>=? str 1 str 2 ) Phép so sánh đc da trên các v t so sánh ký t char-ci=?, char-ci<?, char- ci>?, char-ci<=?, và char-ci>=?. Hàm : (string-copy str) tr v chui mi là bn sao (copy) ca str : (string-copy ”abc”) --> ”abc” Hàm : (substring str k l) tr v bn sao ca str k t ký t có ch s k (k c k) đn ký t có ch s l (không k l). Các giá tr ca k và l phi hp l. (substring "Hello, World!" 0 1) --> ”H” (substring "Hello, World!" 7 12) --> ”World” Hàm substring có th đnh ngha li nh sau : (define my-substring (s1 m n) (let ((s2 (make-string (- n m)))) (do ((j 0 (+ j 1)) (i m (+ i 1))) ((= i n) s2) (string-set! s2 j (string-ref s1 i))))) (my-substring "Hello, World!" 7 12) --> ”World” Trong hàm my-substring s dng cu trúc lp do có cú pháp nh sau : (do ((var 1 init 1 step 1 ) . ) (test expr .) command . ) 64 LP TRÌNH HÀM Cu trúc lp do hot đng tng t nh lnh do trong các ngôn ng mnh lnh : bin điu khin var 1 nhn giá tr khi đng init 1 có bc thay đi step 1 (nu có) cho mi ln lp. Khi điu kin lp test cha đc tho mãn (false), biu thc command (nu có) đc thc hin. Khi test đc tho mãn (true), các biu thc expr đc tính (t trái qua phi) đng thi là giá tr tr v. (define L '(1 3 5 7 9)) (do ((L L (cdr L)) (sum 0 (+ sum (car L)))) ((null? L) sum)) --> 25 III.2 Kiu d liu vect Vect là kiu d liu gm mt dãy các phn t tng t kiu chui, nhng mi phn t có th có kiu bt k, không hoàn toàn ký t. Mi phn t ca vect li có th là mt vect, t đó to thành vect có nhiu chiu (multidimensional vector). Trong Scheme, các phn t ca vect đc đt trong mt cp du ngoc (), ngay sát trc cp du ngoc có đt mt du # (number sign). ’#(999 #\a ”Kiki” (1 2 3) ’x) --> ’#(999 #\a ”Kiki” (1 2 3) ’x) S dng hàm vector đ to ra mt vect các s nguyên nh sau : (vector 1 2 3 4 5) --> ’#(1 2 3 4 5) (vector ’x ’y ’z) --> ’#(x y z) Hàm make-vector đ to ra mt vect có đ dài n đnh trc : (make-vector 3) --> ’#(#{Unspecific} #{Unspecific} #{Unspecific}) (make-vector 3 ”Kiki”) --> ’#(”Kiki” ”Kiki” ”Kiki”) Tng t kiu chui, các hàm vector-ref và vector-set! dùng đ tip cn và thay đi tng ng tng phn t ca vect. V t vector? dùng đ kim tra kiu vect : (vector? ’#(x y z)) --> #t S dng cu trúc do, ta to ra mt vect các s t nhiên nh sau : (do ((v (make-vector 5)) (i 0 (+ i 1))) ((= i 5) v) (vector-set! vec i i)) --> ’#(0 1 2 3 4) KIU D LIU PHC HP 65 III.3 Kiu d liu b đôi III.3.1. Khái nim tru tng hoá d liu Tru tng hoá th tc (procedure abstraction) là xây dng các ng dng phc tp t nhng thao tác đn gin, bng cách che du trong chng mc có th nhng chi tit x lý. Tru tng hoá d liu cng nhm mc đích đnh ngha mt lp d liu phc tp và cách thao tác trên các d liu đó mà không quan tâm đn cách biu din và cài đt chúng trong máy vt lý nh th nào. Phng pháp tru tng hoá d liu đc ng dng rng rãi trong lp trình hng đi tng. Mt cu trúc d liu tru tng hay kiu d liu tru tng đc đnh ngha, hay đc đc t (specification) bi 4 thành phn : tên kiu d liu tru tng (types), các đnh ngha hàm (functions), các điu kin đu (preconditions) nu có và các tiên đ (axioms). Hai thành phn đu mô t cú pháp v mt cu trúc thuc tính ca kiu d liu tru tng, hai thành phn sau mô t ng ngha. Thành phn functions lit kê các khuôn mu hàm (function pattern). Mi khuôn mu hàm, còn đc gi là mt ký pháp (signature), có dng mt ánh x cho bit kiu ca các tham đi và ca kt qu nh sau : Tên-hàm : min-xác-đnh − > min-tr Ngi ta thng phân bit ba loi hàm là hàm kin to (constructor) đ to ra kiu d liu mi, hàm tip nhn (accessor) đ trích ra các thuc tính và hàm bin đi (transformator) đ chuyn kiu d liu. Do các hàm không phi luôn luôn xác đnh vi mi d liu nên ngi ta cng phân bit các hàm toàn phn (total functions) và các hàm b phn (partial functions). Trong trng hp các hàm là b phn, ngi ta cn cung cp các điu kin đu là các ràng buc trên min xác đnh ca hàm. Mt li gi hàm không tuân theo điu kin đu đu dn đn sai sót (chia cho 0, tính cn bc hai ca mt s âm, v.v .). Chng hn, điu kin đu ca hàm to s hu t (create-rat n d) là mu s d≠0. Thành phn preconditions có th vng mt nu không có điu kin đu. Thành phn axioms mô t các chc nng vn dng hàm, phi đc khai báo rõ ràng, đy đ và d hiu. Mi vn dng hàm có dng mt mnh đ lôgích hp thc luôn có giá tr true, ngha là mt hng đúng (tautology). Khi cn s dng các bin, ngi ta s dng t khoá var đ khai báo trc tên các bin, tng t trong các ngôn ng lp trình mnh lnh nh C, Pascal . Chú ý rng kiu tin đnh number cng là mt kiu tru tng : bi vì ta có th bit các phép toán s hc trên các s nh +, −, *, . nhng ta li không bit cách biu din chúng trong b nh. Chng hn sau đây là đc t kiu s t nhiên Ν (natual number) : types nat functions 0 : -> nat ; 0 là s t nhiên đu tiên, là mt hng (constant) succ : nat -> nat ; hàm successor ly phn t k tip + : nat × nat -> nat – : nat × nat -> nat * : nat × nat -> nat ^ : nat × nat -> nat = : nat × nat -> boolean 66 LP TRÌNH HÀM axioms var X, Y : nat X + 0 == X X + succ(Y) == succ(X + Y) 0 – X ⇔ 0 ; ch làm vic vi các s t nhiên X – 0 ⇔ X succ(X) – succ(Y) ⇔ X – Y X * 0 ⇔ 0 X * succ(Y) ⇔ X + (X * Y) X ^ 0 ⇔ succ(0) X ^ succ(Y) ⇔ X * (X ^ Y) 0 = 0 ⇔ true succ(X) = 0 ⇔ false 0 = succ(X) ⇔ false succ(X) = succ(Y) ⇔ X = Y III.3.2. nh ngha b đôi Trong ngôn ng Scheme, mt b đôi, hay còn đc gi là cp có du chm (dotted pair), là kiu d liu phc hp tng t bn ghi gm mt cp giá tr nào đó có th t. Có mt du chm đ phân cách hai giá tr lu gi trong b đôi và các du cách đ phân cách gia du chm và các giá tr. Phn t (trng) th nht đc gi là car, phn t th hai cdr. Các tên car và cdr 1 xut hin khi John Mc. Carthy đ xut ngôn ng Lisp chy trên IBM-704 nm 1956 và đc gi li theo truyn thng. Gi s any là mt kiu d liu nào đó ca Scheme, ký pháp ca cu trúc b đôi doublet đc đc t nh sau : types doublet functions cons : any × any -> doublet car : doublet -> any cdr : doublet -> any pair? : any -> boolean axioms var a, y : any car(cons(x, y)) = x cdr(cons(x, y)) = y T kiu tru tng b đôi, đ to ra b đôi, ngi ta s dng cons : (cons s 1 s 2 ) --> (<giá tr ca s 1 > . <giá tr ca s 2 >) Sau đây là mt ví d v mt b đôi : : (cons ’year 2004) ; gm mt ký hiu và mt s −-> (year . 2004) (cons 29 #t) ; gm mt s và mt tr lôgích −-> (29 . #t) nh ngha bin có giá tr là mt b đôi : 1 car = content of the address register, cdr = content of the decrement register. KIU D LIU PHC HP 67 (define x (cons 1 2)) x --> (1 . 2) (car x) --> 1 (cdr x) --> 2 Trong máy, b đôi đc biên dch nh mt cp con tr tr đn car và cdr. x car cdr 1 2 Hình III.1. Biu din các b đôi nh con tr. Các thành phn car và cdr ca b đôi có vai trò đi xng nhau : hàm car tng ng vi thành phn đu tiên và hàm cdr tng ng vi thành phn th hai. Ta có quan h tng quát nh sau : (car (cons a b)) = <giá tr ca a> (cdr (cons a b)) = <giá tr ca b> (car x) --> 1 x = (1 . 2) (cdr x) --> 2 (cdr (car y)) --> 2 V t pair? dùng đ kim tra s-biu thc có phi là mt b đôi hay không ? (define x ’(1 . 2)) (pair? x) --> #t ; x = (1 . 2) là mt b đôi (pair? (cdr x)) --> #f ;(cdr x) = 2 không phi là mt b đôi V t eq? hay đc dùng đ kim tra hai b đôi có đng nht vi nhau không. Thc cht, eq? kim tra tính đng nht ca hai con tr. Ng ngha ca hàm này nh sau : axioms var x, y : doublet ; a, b : any (x = cons(a, b)) ∧ (y = x) ⇒ (eq?(x) = eq?(y)) Ví d : (define x (cons 1 2)) (define y x) ; c x và y cùng tr đn mt b đôi (eq? x y) --> #t Tuy nhiên : 68 LP TRÌNH HÀM (eq? x (cons 1 2)) --> #f bi vì x không tr đn b đôi mi đc to ra bi cons ! III.3.3. t bin trên các b đôi Nh cons, car, cdr, ta đã đnh ngha các b đôi nh là d liu s cp. T đó, ta có th thay đi b đôi nh các hàm đt bin set-car! và set-cdr!. Các hàm này không to ra b đôi mi, nhng làm thay đi b đôi đang tn ti. Scheme quy c các hàm làm thay đi trng thái mt đi tng có tên gi kt thúc bi du chm than !. Ngi ta gi đó là nhng hàm đt bin (mutator functions). Gi s kiu b đôi đc to ra t hai kiu d liu nào đó ca Scheme là T1 và T2, ta vit quy c doublet(T1, T2), khi đó các hàm set-car! và set-cdr! đc b sung vào phn đc t hàm nh sau : functions set-car! : doublet(T1, T2) × T1 → any set-cdr! : doublet(T1, T2) × T2 → any Ng ngha ca các hàm này nh sau : axioms var x : doublet(T1, T2) ; a, a1 : T1, b, b1 : T2 (x = cons(a, b)) ∧ (set-car!(x, a1)) ⇒ (car(x) = a1) (x = cons(a, b)) ∧ (set-cdr!(x, b1)) ⇒ (cdr(x) = b1) Gi s ta có b đôi : (define x (cons 1 2)) x --> (1 . 2) 1 x 2 1 2 x 4 3 (a) (b) Hnh III.3.1. Biu din các b đôi đt bin. Trc (a) và sau khi (b) thay đi b đôi Khi đó nu thc hin : (set-car! x 3) (set-cdr! x 4) thì giá tr ca con tr x không thay đi, c hai trng hp đu cùng tr đn mt b đôi. Tuy nhiên trong trng hp sau, ni dung ca b đôi đã thay đi, lúc này b đôi cha hai con tr tr đn hai v trí biu din ln lt 3 và 4. Riêng hai v trí cha ln lt 1 và 2 vn nh c. Kim tra giá tr ca con tr x : x --> (3 . 4) [...]... (primes ’(2 3 5 7 11 71 73 79 83 149 151 157 227 229 233 30 7 31 1 31 3 38 9 39 7 401 467 479 487 III.4.2.5 K thu t 13 17 19 23 29 31 37 41 43 47 53 59 61 67 89 97 101 1 03 107 109 1 13 127 131 137 139 1 63 167 1 73 179 181 191 1 93 197 199 211 2 23 239 241 251 257 2 63 269 271 277 281 2 83 2 93 317 33 1 33 7 34 7 34 9 35 3 35 9 36 7 37 3 37 9 38 3 409 419 421 431 433 439 4 43 449 457 461 4 63 491 499) quy x lý danh... #\A #\a) > #f (string=? "1 23" "1 23" ) > #t (eqv? #\A #\A) > #t (eqv? 'toto 'toto) > #t (eqv? "1 23" "1 23" ) > #t (equal? "1 23" "1 23" ) > #t V t eqv?, hay eq?, dùng so sánh các ki u d li u b t k , k t qu s là #t n u chúng cùng m t i t ng Riêng ki u d li u danh sách nên s d ng v t so sánh string=? (eq? 1 23 1 23) > #t 92 L P TRÌNH HÀM (eq? 1 234 5678901 234 5678901 1 234 5678901 234 5678901) > #f (eq? ’(1 ... ’a ’(b c a d e)) > (a d e) (memq ’a ’(b c d e g)) > #f (memq ’a ’(b a c a d a)) > (a c a d a) (memv 3. 4 ’(1.2 2 .3 3.4 4.5)) > (3. 4 4.5) (memv 3. 4 ’(1 .3 2.5 3. 7 4.9)) > #f (member ’(b) ’((a) (b) (c))) > ((b) (c)) (member ’(d) ’((a) (b) (c))) > #f (member ”b” ’("a" "b" "c")) > (”b” ”c”) III.4.2 .3 D ng case x lý danh sách D ng case t ng t cond nh ng th pháp c a d ng case nh sau : (case s (L1 body1)... (cons (cons ’()) )) Ví d : (list (cons 1 2) (cons 3 4)) > ((1 2) (3 4)) ; (1 2) và (3 4) là các b Hàm list nh n m t s tham i tùy ý là các s-bi u th c h p t các giá tr c a các tham i ó Ví d : ôi tr v m t danh sách m i t (list 1 2 3) > (1 2 3) (list ’(a b) ’(c d) ’(c d) ’() ’((e))) > ((ab) (cd) () (e)) Danh sách sau ây g m 3 ph n t , ph n t th nh t là d u + : ’(+ 1 2) > (+ 1 2) Chú... V1) (car V2)) (equal? (cdr V1) (cdr V2)))) (else #f))) ; các i t ng có b n ch t khác nhau (equal? > #t (equal? > #t (equal? > #t (equal? > #t #\a #\a) "1 23" "1 23" ) '(1 2) '(1 2)) '(1 2 3 4 5) '(1 2 3 4 5) ) III.4 .3 Bi u di n danh sách III.4 .3. 1 Bi u di n danh sách b i ki u b ôi M t danh sách khác r ng là m t b ôi c bi t : ch ng h n danh sách có m t ph n t (a) chính là b ôi ’(a ()) có ph n t th... ’(a > ’() (list-tail ’(a > ’(c d) (list-tail ’(a > d b c) 0) b c) 2) b c) 3) b c d) 2) b c d) 3) (define week-end (list-tail week-list 5)) week-end > (samedi dimanche) V t (list? L) ki m tra L có ph i là m t danh sách không : (list? > #t (list? > #t (list? > #f (list? > #f (list? > #f ’()) ’(a b c)) ’a) ’ (3 4)) 3) 3 Các hàm chuy n i ki u (string->list str) (list->string L) (string->number... 2 1 3 5 Hình III.8 t bi n c a C c ng là t bi n c a D Ng i ta c ng có th ti t ki m c nhi u b nh b ng cách bi u di n m i b ôi trong m t n v nh Sau ây ta xét m t ví d v kh n ng x y ra hi u ng ph khi th c hi n các phép t bi n trên các danh sách (define X (list 1 2 3 4)) (define Y (cdr X)) ; X và Y có cùng danh sách con (2 3 4) (set-car! X 5) ; thay i X mà không nh h ng n Y X > (5 2 3 4) Y > (2 3 4)... (define (value-y R) (cdr (car (define (value-L R) (car (cdr (define (value-H R) (cdr (cdr Ví d : (define R (cons-rectangle 1 2 R > '((1 2) 3 4) ; t ng c xây d ng nh sau : H) H))) R))) R))) R))) R))) 3 4)) ng v i '((1 2) (3 4)) 74 L P TRÌNH HÀM (value-L R) > 3 (value-H R) > 4 III.4 Ki u d li u danh sách III.4.1 Khái ni m danh sách Khi gi i m t s bài toán, ng i ta th ng ph i nhóm nhi u d li u thành... (null? L) 0 (+ 1 (length (cdr L))))) Hàm length có chi phí tuy n tính Ví d : (length (list 1 2 3) ) > 3 (= (length (list 1 2 3 4)) 0) > #f Các danh sách r ng có th d ng tr c ki n ’() Ví d : c t o ra b i hàm (list) không có tham i, ho c s (= (length (list)) 0) > #t (= (length ’()) 0) > #t (null? (list 1 2 3 4)) > #f (null? (list)) > #t (null? ’()) > #t Scheme không th a nh n d ng ’() là m t bi u... L-congviec-10-10-2000 ’(thu-hai (sang (9h doc- thu) (9h -30 chuan-bi-len-lop) (10h len-lop) (12h an-trua)) (chieu (14h tham-gia-chuyen-de) (16h den-cuoc-hen)))) Ki u d li u danh sách c n có th thu t có th c vào và in ra Scheme cho phép xây d ng các danh sách không thu n nh t (heterogeneous list) v ki u Ch ng h n : (define L ’(1 (2 3) x "bonjour")) (list-ref L 0) > 1 (list-ref L 3) > "bonjour" Tr tr ng h p ng . (1 2 3) ’x) --> ’#(999 #a ”Kiki” (1 2 3) ’x) S dng hàm vector đ to ra mt vect các s nguyên nh sau : (vector 1 2 3 4 5) --> ’#(1 2 3 4 5). (cons-rectangle 1 2 3 4)) R --> '((1 . 2) 3 . 4) ; tng đng vi '((1 . 2) . (3 . 4)) b V y 0 x a L H 74 LP TRÌNH HÀM (value-L R) --> 3 (value-H