2013-03-22 66 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)))))))