Datalogi, grundkurs 1 Lösningsförslag till tentamen 19:e maj 2000
1. a. (4p) I koden finns två fel. i. I den inre funktionen ser vi att argumentet in referensanropas. Det får till följd att listan förstörs, eftersom element efter element tas bort. ii. Funktionsnamnet inner används som en vanlig variabel i satsen inner:= inner + 1; Den rättade koden kan ha följande utseende: FUNCTION count(var lista : list):integer; FUNCTION inner(el : elementpointer):integer; VAR antal : INTEGER; antal:=0; WHILE el<> NIL DO el:=el^.next; antal:=succ(antal); inner:=antal; { inner } count:=inner(lista.first) { count } b. (4p) (define (count lista) (define (inner lista res) (if (null? lista) res (inner (cdr lista) (+ 1 res)))) (inner lista 0)) c. (2p) Nej, samma problem uppstår inte. Det första problemet kan inte uppstå eftersom hela listan kopieras vid anropet. Det andra problemet har vi eliminerat genom att införa en resultatvariabel. 2. a. (2p) Se föreläsningsanteckningarna i kursbunten. b. (2p) Se kurslitteraturen. c. (2p) Se kurslitteraturen. 1
3. (8p) PROGRAM kryptera(hemlis); VAR hemlis, tmp : TEXT; letterset : SET OF Char; c : Char; letterset:=[ A.. Z ]; ReSet(hemlis); ReWrite(tmp); WHILE NOT EoF(hemlis) DO IF hemlis^ IN letterset THEN c:=hemlis^; IF c = Y THEN c:= A ELSE IF c = Z THEN c:= B ELSE c:=succ(succ(c)); Write(tmp,c); END ELSE IF EoLn(hemlis) THEN WriteLn(tmp) ELSE Write(tmp,hemlis^); get(hemlis) ReSet(tmp); ReWrite(hemlis); WHILE NOT EoF(tmp) DO IF EoLn(tmp) THEN WriteLn(hemlis) ELSE Write(hemlis,tmp^); get(tmp); END END. 2
4. a. (2p) TYPE animals = (groda,insekt,liten,stor,resten); aname = ARRAY [1..100] OFCHAR; elementpointer = ^element; element = RECORD name : aname; number : Integer; next : elementpointer wildlife = ARRAY [groda..resten] OFelementPointer; Strukturen som väljs för grupperna är en vektor, detta eftersom man vet att antalet grupper är 5. Strukturen som väljs för sorterna är en länkad lista, detta eftersom antalet sorter kan variera alltså behövs en lista som kan växa dynamiskt. Index till vektorn görs med fördel med hjälp av en egendefinierad typ, i mitt fall kallas den animals. Index avspeglar då mycket väl den verklighet som avbildas. b. (6p) Observera att en ny lista ska skapas med information från de utsorterade elementen, därför kopieras innehållet. FUNCTION allelementsunderlimit(el : elementpointer) : elementpointer; CONST limit = 10; VAR nylista, tmp : elementpointer; nylista:=nil; WHILE (el <> NIL) DO IF (el^.number < limit) THEN New(tmp); tmp^:=el^; tmp^.next:=nylista; nylista:=tmp el:=el^.next; allelementsunderlimit:=nylista; { allelementsunderlimit } {Den nya listan initieras.} {Skapar ett nytt element.} {Kopiering av innehållet.} {Lägger till ett nytt element} {i den nya listan.} 3
c. (3p) Hur man har gjort selektorer, predikat och konstruktorer kan skilja mycket beroende på hur man löst uppgiften. (define (makeinvlist) (list (groda) (insekt) (liten) (stor) (resten))) (define (getfroggroup invlist) (car invlist)) (define (getinsektgroup invlist) (car (cdr invlist))) (define (getlitengroup invlist) (car (cddr invlist))) (define (getstorgroup invlist) (car (cdddr invlist))) (define (getrestengroup invlist) (car (cddddr invlist))) (define (getsortlist group) (cdr group)) (define (emptygroup? sortlist) (null? sortlist)) (define (firstsort sortlist) (car sortlist)) (define (restsortlist sortlist) (cdr sortlist)) (define (sortname sort) (car sort)) d. (7p) (define (getinfo name invlist) (cond ((member? name (getsortlist (getfroggroup invlist))) (list groda (pickoutsort name (getsortlist (getfroggroup invlist))))) ((member? name (getsortlist (getinsektgroup invlist))) (list insekt (pickoutsort name (getsortlist (getinsektgroup invlist))))) ((member? name (getsortlist (getlitengroup invlist))) (list liten (pickoutsort name (getsortlist (getlitengroup invlist))))) ((member? name (getsortlist (getstorgroup invlist))) (list stor (pickoutsort name (getsortlist (getstorgroup invlist))))) ((member? name (getsortlist (getrestengroup invlist))) (list resten (pickoutsort name (getsortlist (getrestengroup invlist))))) (else ()))) 4
(define (member? name sortlist) (cond ((emptygroup? sortlist) #f) ((eq? name (sortname (firstsort sortlist))) #t) (else (member? name (restsortlist sortlist))))) (define (pickoutsort name sortlist) (if (eq? name (sortname (firstsort sortlist))) (firstsort sortlist) (pickoutsort name (restsortlist sortlist)))) 5