Idag: Par och listor Symboler Hur hanterar man icke-numeriska problem? Hur hanterar man en samling av data? Hur konstruerar man sammansatta datastrukturer? Bra om du har läst följande avsnitt i AS: Pair i avsnittet: Example: Arithmetic Operations for Rational Numbers Inledningen i avsnittet: Hierarchical Data and the Closure Property Representing Sequences. Symboler används för att uttrycka icke-numeriska data såsom namn, adress, bilregisternummer, boktitel, osv. > (define namn1 Kalle) > namn1 Kalle > (define adress1 Lindstedtsvagen3) > adress1 Lindstedtsvagen3 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 1 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 2 / 29 Symboler... Symboler... Scheme skiljer på gemener och versaler i symboler. > (eq? Kalle kalle) #f > (eq? kalle kalle) #t Predikatet eq? testar om två symboler är lika. Använd inte predikatet =, det duger bara till numerisk jämförelse. Använd inte heller mellanslag eller någon av symbolerna ( ) [ ] { } ;, # \ i symbolnamnen. Alternativt kan man använda textsträngar (define address Lindstedtsvägen 3 ) Stränghantering är långsammare än symbolhantering, men man kan använda alla tecken i strängarna. DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 3 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 4 / 29
Listor Listor... I många situationer har man behov av listor, t.ex. shoppinglistor, namnlistor, adresslistor, tidtabeller,... I Scheme kallar man tal, symboler, och listor för objekt. Tal och symboler kallas för atomära objekt medan listor kallas för sammansatta objekt. En lista kan konstrueras med hjälp av proceduren list: > (define namelist (kalle pelle lasse)) > namelist (kalle pelle lasse) > (define numberlist (1 2 3 4 5)) > numberlist (1 2 3 4 5) >(list kalle pelle lasse) (kalle pelle lasse) eller med proceduren cons: >(cons kalle (pelle lasse)) (kalle pelle lasse) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 5 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 6 / 29 Listor... Listor... Lägg märke till att proceduren list tar ett godtyckligt antal listelement som argument medan proceduren cons tar ett listelement och en lista som argument. Proceduren car används för att hämta det första elementet i en lista: Proceduren cdr används för att hämta ut resten av listan (d.v.s. listan utan det första elementet): > (cdr namelist) (pelle lasse) > (define namelist (kalle pelle lasse)) > (car namelist) kalle > namelist (kalle pelle lasse) namelist är oförändrad efter anropet av car! car och cdr används ofta tillsammans för att hantera listor. Om vi t.ex. vill hämta ut det n:te elementet i en lista: (define nth-element (lambda (n a-list) (if (= n 1) (car a-list) (nth-element (- n 1) (cdr a-list))))) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 7 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 8 / 29
Listor... Listor... Testa även att argumentet är en lista och att listan har minst n element: (define nth-element (lambda (n a-list) (cond ((not (list? a-list)) ()) ((null? a-list) ()) ((<= n 0) ()) ((= n 1) (car a-list)) (else (nth-element (- n 1) (cdr a-list)))))) Men det är onödigt att testa varje anrop: (define nth-element (lambda (n a-list) (define inner (lambda (n a-list) (if (= n 1) (car a-list) (inner (- n 1) (cdr a-list))))) (cond ((not (list? a-list)) ()) ((null? a-list) ()) ((<= n 0) ()) (else (inner n a-list))))) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 9 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 10 / 29 Mer om par och listor cons? car? cdr? Axiom: x = (car (cons x y)) y = (cdr (cons x y)) Man realiserade språket LISP först på en dator av modellen IBM704. Fantasin tröt lite och man använde datorminnets namn på datorord-delar. Ett dator- ord i IBM704 var 36 bitar långt och bestod av fyra delar (längden i bitar inom parentes): (cons 1 2) bildar ett par (1. 2) som med pilar och boxar ser ut så här: 2 Address Register (15), Decrement Register (15), Prefix Register (3), Tag Register (3) 1 car = Contents of address register cdr = Contents of decrement register cons = Construct (lägg in data i ett register) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 11 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 12 / 29
(cons 1 (cons 2 (cons 3 ()))) (1 2 3) I en lista är sista referensen alltid () (inget objekt) ger en lista med 3 element (cons 1 ()) (1) ger en lista med 1 element. 1 2 3 (car (cons 1 (cons 2 (cons 3 ())))) 1 Så Scheme ser ingen skillnad mellan en lista och en sekvens av par med sista referensen (= ()) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 13 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 14 / 29 > (cdr (1 2 3)) (2 3) > (car (cdr (1 2 3))) 2 > (cadr (1 2 3)) 2 > (cddr (1 2 3)) (3) I stället för (cons 1 (cons 2 (cons 3 ()))) kan man skriva (list 1 2 3) > (caddr (1 2 3)) 3 > (cdddr (1 2 3)) () DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 15 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 16 / 29
Betrakta följande (cons (cons 1 2) (cons 3 4)) skrivs av schemesystemet som ((1. 2). (3. 4)) och representeras av pil-box-diagrammet (cons (cons 1 (cons 2 3)) 4) skrivs av schemesystemet som ((1 2. 3). 4) och representeras av pil-box-diagrammet 4 4 2 3 3 1 1 2 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 17 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 18 / 29 En lista av elementen 1, 2, 3 och 4 kan göras på följande sätt: (list 1 2 3 4) eller (1 2 3 4) där förhindrar evaluering. Man kan sätta ihop dem på alla möjliga sätt också > (cons (list 1 2) (list 3 4)) ((1 2). (3 4)) > (list (list 1 2) (list 3 4)) ((1 2) (3 4)) > (define x (1 2 3)) > (cons 0 x) > (cons x 0) > (cons 1 (cons 2 ())) > (cons 1 (list 2)) > (list 1 2) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 19 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 20 / 29
Procedurer som opererar på listor Längden på en lista Sätt in ett nytt element sist i en lista (define length (lambda (a-list) (if (null? a-list) 0 (+ 1 (length (cdr a-list)))))) (define append-element (lambda (x a-list) (if (null? a-list) (cons x ()) (cons (car a-list) (append-element x (cdr a-list)))))) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 21 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 22 / 29 Slå ihop två listor Addera alla tal i en lista (med bara tal i) (define append (lambda (x y) (if (null? x) y (cons (car x) (append (cdr x) y))))) (define add-items (lambda (a-list) (if (null? a-list) 0 (+ (car a-list) (add-items (cdr a-list)))))) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 23 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 24 / 29
Gör en lista med n kopior av elementet element Dubblera värdet av alla element i en lista (define repeat (lambda (n element) (if (= n 0) () (cons element (repeat (- n 1) element))))) (define double-all (lambda (a-list) (if (null? a-list) () (cons (* 2 (car a-list)) (double-all (cdr a-list)))))) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 25 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 26 / 29 Ta bort alla förekomster av ett element i en lista Filtrera en lista (define delete (lambda (element a-list) (cond ((null? a-list) ()) ((= element (car a-list)) (delete element (cdr a-list))) (else (cons (car a-list) (delete element (cdr a-list))))))) >(filter even? (1 2 3 4 5 6)) (2 4 6) (define filter (lambda (p? a-list) (cond ((null? a-list) ()) ((p? (car a-list)) (cons (car a-list) (filter p? (cdr a-list)))) (else (filter p? (cdr a-list)))))) DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 27 / 29 DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 28 / 29
Nästa gång: Datarepresentation Om vi hittar på en representation för t.ex. rationella tal, kanske lagrar dem som talpar, och programmerar upp en mängd operationer för att manipulera dem vad händer om vi ändrar representationen? Kan vi vara smarta? DA2001 (Föreläsning 6) Datalogi 1 Hösten 2013 29 / 29