2011-04-21 56 views
11

這是刪除列表的最後一個元素的功能。 。幫助解釋Scheme在計劃中的作用?

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

所以從我的理解,如果我們cons列表(例如a b c對空列表,即'(),我們應該得到 a b c然而,測試中的交互窗口(DrScheme),其結果是:

如果(利弊 '()'(ABC))

(() a b c) 

如果(利弊 '(ABC)'())

((a b c)) 

我喜歡什麼heck :(! 然後我回到我的問題,刪除所有具有相鄰重複的元素。例如, (a b a a c c)將是(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)))) 
     ) 

) 

這是不正確的,但我知道答案有a b一個.之間。這怎麼會發生?

`(a . b)` 

現在只有一個呼叫cons在我上面的代碼,我看不出哪一部分可能會產生此.。任何想法?

感謝,

回答

27

cons構建對,而不是列表。 Lisp解釋器使用'點'來在視覺上分離對中的元素。所以(cons 1 2)將打印(1 . 2)carcdr分別返回一對的第一和第二元素。列表建立在成對之上。如果一對中的cdr指向另一對,則該序列將被視爲一個列表。最後一對的cdr將指向一個名爲null(由'()表示)的特殊對象,這告訴解釋器它已經到達列表的末尾。

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

list過程提供了創建列表的快捷方式:

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

表達(cons '(a b c)())創建一對,其第一元件是例如,列表'(a b c)通過評估以下表達式構建列表

您的remove-dup過程在else子句中創建一對。相反,它應該遞歸地調用remove-dup並將結果作爲該對的第二個元素創建一個列表。我已經清理過程一點:

(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)) 

測試:

> (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) 

另請參見2.2節(分層數據和封閉性)的SICP

爲了完整起見,這裏是remove-dup一個版本中刪除所有相同的相鄰元件:

(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

優雅的答案。萬分感謝 ;) – Chan 2011-04-21 22:57:12

1

在這裏,在僞代碼:

類對{左 對象, 對象右}。

function cons(Object left,Object right){return new Pair(left,right)};

所以, 1.利弊( 'A,' B)=>對( 'A,' B) 2.利弊( 'A,NIL)=>對(' A,NIL) 3.缺點(NIL,'A)=>對(NIL,'A) 4. cons('A,cons('B,NIL))=> Pair('A,Pair('B,NIL)) 5. cons ('A'B),NIL))=>對(對('A,'B),無)

讓我們來看所有情況下的左派和權利: 1.'A和'B是原子,並且整個Pair不是一個列表,所以(const'a'b)在方案 中給出(a。b)2. NIL是一個空列表,'A是一個原子,(cons'a'())給出列表(a) 3. NIL和'A同上,但是左邊是列表(!),(cons'()'a)給出對(()。a) 4.容易的情況下,我們在這裏有適當的列表(a b)。 5.正確的清單,頭是雙(a。b),尾是空的。

希望,你明白了。

關於你的功能。你在LIST上工作,但構建了對。 列表是成對的(成對的),但不是所有的成對都是列表!成對列表必須有NIL作爲尾部。

(a b)pair & list (a。b)對沒有列表

儘管缺點,你的函數有錯誤,但它不適用於'(a b a a c c d)。由於這與您的問題無關,因此我不會在此處發佈修復。