2011-04-21 5 views
11

Ta funkcja usuwa ostatni element z listy. ..Pomoc w wyjaśnieniu, jak działa "cons" w schemacie?

(define (remove-last ll) 
    (if (null? (cdr ll)) 
     '() 
     (cons (car ll) (remove-last (cdr ll))))) 

Więc z mojego zrozumienia, jeśli cons lista (np a b c z pustą listę, tzn '(), powinniśmy dostać a b c Jednak badania w oknach interakcji (DrScheme), wynik był:

Jeśli (przeciw '() (ABC))

(() a b c) 

Jeśli (przeciw '(ABC),'())

((a b c)) 

Jestem jak co do cholery :(! Potem wróciłem do mojego problemu, usunąłem wszystkie elementy, które mają sąsiedni duplikat. Na przykład (a b a a c c) będzie (a b).

(define (remove-dup lst) 
    (cond ((null? lst) '()) 
     ((null? (cdr lst)) (car lst)) 
     ((equal? (car lst) (car (cdr lst))) (remove-dup (cdr (cdr lst)))) 
     (else (cons (car lst) (car (cdr lst)))) 
     ) 

) 

To nie była prawidłowa, jednak zdaję sobie sprawę odpowiedź mają . między a b. Jak to mogło się stać?

`(a . b)` 

było tylko jedno wezwanie do cons w moim kodu powyżej, nie mogłem zobaczyć, jaka część może generować ten .. Dowolny pomysł?

Dzięki,

Odpowiedz

27

budować pary, a nie listy. Tłumacze Lisp używają "kropki" do wizualnego rozdzielenia elementów w parze. Tak więc (cons 1 2) wydrukuje (1 . 2). car i cdr odpowiednio zwracają pierwszy i drugi element pary. Listy są budowane na szczycie par. Jeśli cdr pary wskazuje na inną parę, ta sekwencja jest traktowana jako lista. Numer cdr ostatniej pary wskaże specjalny obiekt o nazwie null (reprezentowany przez '()), który informuje tłumacza, że ​​dotarł do końca listy. Na przykład, lista '(a b c) wykonana jest przez ocenę następujące wyrażenie:

> (cons 'a (cons 'b (cons 'c '()))) 
(a b c) 

Procedura list dostarcza skrót dla tworzenia list:

> (list 'a 'b c) 
(a b c) 

Wyrażenie (cons '(a b c)()) tworzy parę którego pierwszy element jest lista.

Twoja procedura remove-dup tworzy parę w klauzuli else. Zamiast tego powinien utworzyć listę przez rekursywne wywołanie remove-dup i umieszczenie wyniku jako drugiego elementu pary. Mam oczyścić procedura trochę:

(define (remove-dup lst) 
    (if (>= (length lst) 2) 
     (if (eq? (car lst) (cadr lst)) 
      (cons (car lst) (remove-dup (cddr lst))) 
      (cons (car lst) (remove-dup (cdr lst)))) 
     lst)) 

testy:

> (remove-dup '(a b c)) 
(a b c) 
> (remove-dup '(a a b c)) 
(a b c) 
> (remove-dup '(a a b b c c)) 
(a b c) 

Patrz także sekcja 2.2 (hierarchiczny danych oraz zamknięcia nieruchomości) w SICP.

Dla kompletności, tutaj jest wersją remove-dup że usuwa wszystkie identyczne sąsiednie elementy:

(define (remove-dup lst) 
    (if (>= (length lst) 2) 
     (let loop ((f (car lst)) (r (cdr lst))) 
     (cond ((and (not (null? r))(eq? f (car r))) 
       (loop f (cdr r)))    
       (else 
       (cons (car lst) (remove-dup r))))) 
     lst)) 
+0

Elegancki odpowiedź. Wielkie dzięki ;) – Chan

1

Tutaj w Pseudokod:

klasa Pair { Obiekt w lewo, w prawo} obiektu.

function cons (Obiekt po lewej, prawo obiektu) {return new Pair (left, right)};

Więc 1. minusy ('A' B) => Para ('A' B) 2. minusy ('A, NIL) => Para (' A, NIL) 3. minusy (NIL, "A) => Para (NIL," A) 4. cons ("A, przeciw (" B, NIL)) => Para ("A, para (" B, NIL)) 5. cons (minusy ("A" B), NIL)) => Para (para ("A," B), NIL)

Zobaczmy lefty i prawa we wszystkich przypadkach: 1. 'A i' B to atomy , a cała para nie jest listą, więc (const 'a' b) daje (a. b) w schemacie 2. NIL jest pustą listą, a 'A jest atomem, (cons' a '()) daje listę (a) 3. NIL i "A jak wyżej, ale jak po lewej jest lista (!), (cons '()" a) daje parę ((). a) 4. Łatwa sprawa, mamy odpowiednią listę tutaj (a b). 5. Prawidłowa lista, głowa to para (a. B), ogon jest pusty.

Mam nadzieję, że masz pomysł.

Odnośnie funkcji. Pracujesz nad LISTĄ, ale skonstruuj PAIRS. Listy są parami (par), ale nie wszystkie są listami! Aby być parą listy, musisz mieć NIL jako ogon.

(a) para & lista (a.b) para nie lista

Pomimo wad, twoja funkcja ma błędy, po prostu nie działa na "(a b a c c d d). Ponieważ nie jest to związane z twoim pytaniem, nie będę tutaj publikować poprawek.

Powiązane problemy