2010-11-14 89 views
1

這個遞歸函數似乎可以正常工作,向結果列表中添加我想要的確切字母B和C,然後在完成時正確地看到最後一個元素已經到達。方案遞歸錯誤

然後執行基本情況,併發生一個我無法解釋的錯誤。什麼導致了這個錯誤?

(define(preceding-R X Vector result)  
     (if (eq? '() (cdr (vector->list Vector))) 
       result 
       (helper X Vector result))) 

(define (helper X Vector result) 
    (if(eqv? X (cadr (vector->list Vector))) ((set! result (cons result (car (vector->list Vector)))) (preceding-R X (list->vector (cdr (vector->list Vector))) result)) 
          (preceding-R X (list->vector (cdr (vector->list Vector))) result))) 

(preceding-R 'a #(b a c a) '())) 

錯誤:

procedure application: expected procedure, given: #; arguments were: ((() . b) . c)

+1

請格式化您的代碼並簡要說明代碼必須執行的操作。 – ffriend 2010-11-14 01:25:23

回答

4

下面是一些代碼,是不是 「絕對可怕」:

(define preceding-R 
    (lambda (x vec) 
    (define helper 
     (lambda (ls) 
     (cond 
      ((null? ls) '()) 
      ((null? (cdr ls)) '()) 
      ((eq? (cadr ls) x) (cons (car ls) (helper (cdr ls)))) 
      (else (helper (cdr ls)))))) 
    (helper (vector->list vec)))) 

> (preceding-R 'a #(b a c a)) 
(b c) 

禮Barzilay有一個點;如果我是分級的原代碼,我可能會判給超過一半的信貸少,因爲的事情,他指出:

  • set!應該在大多數情況下是可以避免的,並且一般不涉及基本方案代碼作業問題許可。必須使用set!是一個通常的說法,遞歸不是很好理解。
  • 由於begin「拋棄」除最後一個表達式以外的所有結果,這意味着非尾部表達式具有副作用(如set!),所以begin通常也不會在教育問題中出現。
  • 一遍又一遍地來回轉換顯然是一種浪費。一次轉換就可以完成,但你可能可以使用列表而不是向量來開始。列表是Scheme中使用的最常用的數據結構,尤其是因爲它們可以很好地適用於遞歸。
  • 您的代碼會報錯了一個空的列表上的第二行:(preceding-R 'a #()) => Error: Attempt to apply cdr on '()
  • 如果使用set!修改結果,那麼就沒有理由了傳遞的結果。這是額外的行李。
  • 禮的最後一點是,你可以寫:

(define (helper X Vector result) 
    (preceding-R X (list->vector (cdr (vector->list Vector))) 
       (if (eq? X (cadr (vector->list Vector))) 
        (cons (car (vector->list Vector)) result) 
        result))) 

保存一些重複的代碼。

1
(define (preceding-R X Vector result)  
    (if (eq? '() (cdr (vector->list Vector))) 
    result 
    (helper X Vector result))) 

(define (helper X Vector result) 
    (if (eqv? X (cadr (vector->list Vector))) 
    (begin 
     (set! result (cons (car (vector->list Vector)) result)) 
     (preceding-R X (list->vector (cdr (vector->list Vector))) result)) 
    (preceding-R X (list->vector (cdr (vector->list Vector))) result))) 

(preceding-R 'a #(b a c a) '()) 

我已經開始添加通話。如果你想在多個表達式中如果你不能把它們包裝在()中,那麼它被解釋爲在void上的函數調用(由set!返回),其中遞歸調用返回到前面的R所返回的參數。

+0

非常感謝,我知道這個問題與此有關,但我曾嘗試使用cond來解決這個問題,因爲我知道它使用默認開始。顯然我沒有正確實施它。再次感謝。 – cliff259 2010-11-14 01:42:38

+3

這段代碼是絕對可怕的。它使用'set!'沒有任何理由,它使用'begin'就是爲了這個,它會在某些情況下拋出錯誤,它會不斷地將向量轉換成列表並返回向量,它在外層有'if'當它很容易被推到最後一個參數時 – 2010-11-14 01:54:07