2013-03-22 95 views
1

我有一個遞歸函數,基本上保持附加元素列表遞歸,直到滿足條件。雖然有一個問題,那就是使用append,我們必須給它一個引用列表。這樣做計劃:遞歸與列表附加

(append (1 2) 3) 

給了我們一個錯誤。

問題是,當我第一次通過一個列表的參數,我可以把'使它成爲一個引用列表。但是,一旦我追加了一些東西到列表中,並且它被遞歸地傳遞給同一個函數,第二次append試圖工作,它會看到列表不再被引用,所以Scheme認爲它是一個過程而不是列表。讓我告訴你的代碼的簡化版本:

(define simple 
    (lambda (x y) 
     (if (equal? x '()) 
      (display 'success!) 
      (simple (cdr x) (append y (car x)))))) 

我們做(simple '(1 2 3) '()) 我意識到上面的程序是沒用的運行功能;這只是爲了證明我在說什麼。

謝謝!

+0

適用'quote'給個說法 – 2013-03-22 03:12:57

回答

1

與您發佈的代碼的麻煩不說,計劃是混淆了一個列表中的程序;撥打append的麻煩是。

調試時跟蹤過程的執行會很有幫助。下面是當我運行了與追蹤開啓simpleappend你的代碼是怎麼所示,使用trace-define在嬌小的Chez方案:

> (simple '(1 2 3) '()) 
|(simple (1 2 3)()) 
| (append() 1) 
| 1 
|(simple (2 3) 1) 
| (append 1 2) 

因爲(append() 1)回報1,在第一個遞歸調用simple,第二個參數是1而比列表。因此,您在下一次致電append時會收到錯誤消息。

你可能是在呼叫你的包裹通話(car x)list修復:

(define simple 
    (lambda (x y) 
    (if (equal? x '()) 
     (display 'success!) 
     (simple (cdr x) (append y (list (car x))))))) 

這裏是固定的版本運行的跟蹤:

> (simple '(1 2 3) '()) 
|(simple (1 2 3)()) 
| (append() (1)) 
| (1) 
|(simple (2 3) (1)) 
| (append (1) (2)) 
| (1 2) 
|(simple (3) (1 2)) 
| (append (1 2) (3)) 
| (1 2 3) 
|(simple() (1 2 3)) 
success!|#<void> 
0

要將元素附加到列表的末尾,請將該元素置於列表中(append定義爲僅列出)。例如,在你的代碼做到這一點:

(append y (list (car x))) 

當然,這並不能改變一個事實,即程序是什麼都不做,因爲它是。至少,返回累積值在y

(define simple 
    (lambda (x y) 
    (if (equal? x '()) 
     y 
     (simple (cdr x) 
       (append y (list (car x)))))))