Göm menyn

Del K: Strukturändrande funktioner

Exempel K1

Vad blir resultatet av följande uttryck?

  (setq lista '(pelle stina kalle))
  (setq ny-lista lista)
  (equal lista ny-lista)
  (equal lista '(pelle stina kalle))
  (eq lista ny-lista)
  (eq lista '(pelle stina kalle))

Se svar

Exempel K2

Vad blir resultatet av följande uttryck? Rita också den grafiska strukturen (med boxar och pekare) och visa hur den förändras!

  (setq lista '(tallrik tall))
  (setf (first lista) 'gran)
  (setf ny-lista (rest lista))
  (setf (cddr lista) '(ek bok))
  (rest ny-lista)
  (nconc ny-lista (list 'asp))
  lista
  ny-lista

Se svar

Exempel K3

Skriv en funktion ändra-assoc som på en associationslista ändrar högra delen i ett par. Exempel:

  CL-USER(66): (setq huvudstäder '((sverige . stockholm)
                               (norge . oslo)
                                   (brasilien . rio)))
  ((SVERIGE . STOCKHOLM) (NORGE . OSLO) (BRASILIEN . RIO))
  CL-USER(67): (ändra-assoc huvudstäder 'brasilien 'brazilia)
  BRAZILIA
  CL-USER(68): huvudstäder
  ((SVERIGE . STOCKHOLM) (NORGE . OSLO) (BRASILIEN . BRAZILIA))

Se svar

Exempel K4

Utöka funktionen från föregående uppgift så att den lägger till ett nytt par i associationslistan om det inte finns tidigare. Kalla den nya funktionen för utöka-assoc. Exempel:

  CL-USER(71): (utöka-assoc huvudstäder 'finland 'helsinki)
  ((FINLAND . HELSINKI))
  CL-USER(72): huvudstäder
  ((SVERIGE . STOCKHOLM) (NORGE . OSLO) (BRASILIEN . RIO) 
   (FINLAND . HELSINKI))
  CL-USER(73): (utöka-assoc huvudstäder 'finland 'helsingfors)
  HELSINGFORS
  CL-USER(74): huvudstäder
  ((SVERIGE . STOCKHOLM) (NORGE . OSLO) (BRASILIEN . RIO)
   (FINLAND . HELSINGFORS))

Se svar

Exempel K5

Vi vill ha en funktion cond->if som destruktivt bygger om ett cond-uttryck med två klausuler till ett if-uttryck. Observera att ändringarna ska göras destruktivt och att inga nya cons-celler får skapas. Exempel:

  CL-USER(86): (setq uttryck 
                 '(cond ((endp sekvens) '())
                        (t (+ (first sekvens) (bearbeta (rest sekvens))))))
  (COND ((ENDP SEKVENS) 'NIL) 
        (T (+ (FIRST SEKVENS) (BEARBETA (REST SEKVENS)))))
  CL-USER(87): (cond->if uttryck)
  (IF (ENDP SEKVENS) 'NIL (+ (FIRST SEKVENS) (BEARBETA (REST SEKVENS))))

Se svar

Exempel K6

I en större programvara genererar man Lisp-kod, bl.a. cond-uttryck. I den här processen uppstår ibland onödiga klausuler i cond-uttrycken och det har visat sig vara enklare att ta bort dem i efterhand än att försöka göra om processen. För att spara på minne vill man att de onödiga klausulerna ska tas bort destruktivt. De onödiga klausulerna är dels klausuler där predikatet är nil, dels de klausuler som kommer efter en klausul med predikatet t. Ingen av dessa kommer någonsin att köras ändå. Föreställ dig alltså att du utgår från en lista som kan se ut så här:

  (cond (nil ...) ((endp l) ...) (nil ...) (t ...) ((eq x y) ...))

Denna ska med hjälp av den funktion vi ska bygga reduceras till:

  (cond ((endp l) ...) (t ...))

Definiera en funktion optimera-cond som utför denna uppgift destruktivt (utan att skapa nya cons-celler)!

Se svar


Sidansvarig: Peter Dalenius
Senast uppdaterad: 2004-11-08