2017-04-07 38 views
1

這裏是代碼及其對方案口齒不清我想了解每個行這個代碼是如何在一個列表中刪除重複的,所以這是列表(abaaacc)給出(AB)

(define (rdup ls) 
    (let loop ((ls ls) (current #f)) 
    (cond ((null? ls)    ()) 
      ((null? (cdr ls))   (if (eq? (car ls) current)() ls)) 
      ((eq? (car ls) (cadr ls)) (loop (cdr ls) (car ls))) 
      ((eq? (car ls) current) (loop (cdr ls) current)) 
      (else      (cons (car ls) (loop (cdr ls) (car ls))))))) 

和做工精細以下是我試過

(rdup '(a b a a a c c)) 

,並得到(a b)

我想知道代碼的每一行是如何工作的

+2

我將開始張貼這是更好的格式化代碼。你能否改進代碼的縮進和格式?謝謝。 –

+0

希望現在好轉:) – Ahmad

+0

不是。 LET表格應該縮進。 IF形式也是如此。第二個NULL?形式應該是在自己的路線上。最後一行應該縮進。編輯應該實際上幫助。你能改善嗎?正確縮進代碼是必要的,否則代碼變得更難閱讀和理解。 –

回答

0

我已經添加行號和固定的縮進,使之更容易解釋:

01 (define (rdup ls) 
02 (let loop ((ls ls) 
03 (current #f)) 
04 (cond 
05 ((null? ls) '()) 
06 ((null? (cdr ls)) 
07  (if (eq? (car ls) current) '() ls)) 
08 ((eq? (car ls) (cadr ls)) 
09  (loop (cdr ls) (car ls))) 
10 ((eq? (car ls) current) 
11  (loop (cdr ls) current)) 
12 (else (cons (car ls) 
13  (loop (cdr ls) (car ls))))))) 

行02:您使用let語法的一種特殊形式,以創建一個名爲程序,然後就可以從調用在之內。您正在定義(令人困惑地)循環內部的變量ls,其名稱與循環外部的變量名稱完全相同,從而使內部變量成爲外部變量的初始值。您還定義了第二個參數current,您將初始值設爲#f

線04開始cond

線05(我糾正它,所以它會被引述空列表工作),如果ls爲null返回一個空列表。這將停止該過程並展開堆棧。如果

線06檢查cdr爲空,表明你是列表的最後一個元素上運行。如果這是真的,你去07行,要麼返回一個空列表如果lscar等於current,或返回ls。這也結束了程序並展開堆棧。

08-09行會在一行中查找重複項,如果是,則調用循環過程,使用cdr作爲新列表,car作爲current

線10-11檢查,如果car等於current如果這樣調用與cdr(迭代再次在列表中向下)和current的循環過程。

如果沒有這些條件得到滿足,行12-13將cons創建一個新的列表與調用let的結果-ing的lscar -created上的lscdrlscarloop程序。

如果程序擔任預期,它應該已經返回'(a b c)

這裏有一個,因爲我認爲你的程序是爲了工作,工程:

(define rdup 
    (lambda (l) 
    (reverse (let loop ((lst l) 
       (c '())) 
     (cond 
     ((null? lst) c) 
     (else 
     (if (member (car lst) c) 
      (loop (cdr lst) c) 
      (loop (cdr lst) (cons (car lst) c))))))))) 
+0

非常感謝你的先生,這幫了我很多:) – Ahmad

+0

@Ahmad happy幫助 – querist

+0

@ querist更好地說出我需要的是「消除兩個或多個重複元素的所有子序列」 – Ahmad

相關問題