2011-03-10 66 views
0

我正嘗試使用遞歸刪除列表中的重複項。這是我的。它只會刪除第一個重複,而不是全部。從計劃列表中刪除所有重複成員

我的想法是查看第一個成員,檢查它是否是列表中其餘成員,如果是,再次調用該函數。如果沒有,則使用第一個成員創建一個列表,然後再次調用該函數的結果。我不明白爲什麼它不會刪除所有重複項。

(define (removeDupes L) 
    (cond ((null? L)()) 
     ((list? (member (car L) (cdr L))) removeDupes (cdr L)) 
     (#T (cons ((car L) (removeDupes (cdr L))))))) 

這就是我修改它,它的工作原理!我明白這個缺點有什麼問題。它需要兩個參數,我只給了它一個。我仍然不知道爲什麼第三行沒有工作....

(define (removeDupes L) 
    (cond ((null? L)()) 
     ((list? (member (car L) (cdr L)))(removeDupes(cdr L))) 
     (#T (cons (car L) (removeDupes (cdr L)))))) 

回答

3

有在你的代碼的多個錯誤,但是這可能導致你在這裏報告的問題之一是,你的括號是錯誤的在第三行。您正在嘗試撥打removeDupes,但您的代碼實際上並未這麼做;相反,這種情況下的價值結果是(cdr L)。你能明白爲什麼嗎?

當你解決這個問題時,你會發現你的代碼開始產生錯誤。對於您可能首先遇到的人:請仔細看看您在最後一行如何調用cons。對於下一次可能遇到的問題:請記住()在Scheme中不是自我評估。我認爲如果你關心代碼的間距和佈局,這種事情就更難了,比如在每個列表的元素之間放置空格,直到你對這些東西非常熟悉,這些錯誤會停止發生,您可能希望習慣於在遇到一個神祕錯誤時檢查括號:在表達式開始時是否錯過了(,或者在函數的參數之前加了一個額外的(,或者忘記了一個cond條款,或等等等等等等等等不必擔心:過了一段時間它會停止發生...)

+0

我已經修復了格式化,但沒有任何當然,這些東西確實是虛假的。 :-) – 2011-03-11 00:27:47

+1

重新編輯:我強烈建議[Paredit](http://mumble.net/~campbell/emacs/paredit.html)做任何類型的Lisp和Scheme編碼。它確保了括號始終保持平衡,以及許多其他有用的功能。 – 2011-03-11 00:33:48

+2

好的,你修復了所有的錯誤。雖然你不知道爲什麼它有幫助,但有點擔心!也許你錯過了以下非常重要的事情:Scheme中的圓括號根本不扮演*與數學中的括號相同的角色。 '((x))'和'(x)'不是同一個東西,它和'x'不是一回事。一般來說,在Scheme代碼中,列表'(a b c d)'意味着:用'b','c','d'作爲參數來調用函數'a'。如果你把它變成'((a b c d))'或'(a(b c)d)',那麼意思就完全不同了。 – 2011-03-11 01:49:50