Recursion 方案:带列表附加的递归

Recursion 方案:带列表附加的递归,recursion,scheme,Recursion,Scheme,我有一个递归函数,它基本上一直递归地将元素追加到列表中,直到满足条件为止。但是有一个问题,那就是要使用append,我们必须给它一个引用列表。这样做 (append (1 2) 3) 给了我们一个错误 问题是,当我第一次将列表传递给参数时,我可以将“放在一个带引号的列表中。然而,一旦我将某个东西附加到该列表中,并且它再次递归地传递到同一个函数,第二次append尝试工作时,它将看到该列表不再被引用,因此Scheme认为它是一个过程而不是列表。让我向您展示代码的简化版本: (define s

我有一个递归函数,它基本上一直递归地将元素追加到列表中,直到满足条件为止。但是有一个问题,那就是要使用
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'(1233)())来运行函数
我意识到上面的程序是无用的;这只是为了证明我在说什么


谢谢

要将元素追加到列表的末尾,请将元素放入列表中(
append
仅在列表之间定义)。例如,在代码中执行以下操作:

(append y (list (car x)))
当然,这并不能改变这个事实,即过程实际上什么也没做。至少,返回在
y
中累积的值:

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

要将元素追加到列表的末尾,请将元素放入列表中(
append
仅在列表之间定义)。例如,在代码中执行以下操作:

(append y (list (car x)))
当然,这并不能改变这个事实,即过程实际上什么也没做。至少,返回在
y
中累积的值:

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

您发布的代码的问题不是方案将过程与列表混淆;问题在于调用
append

在调试时跟踪过程的执行可能会有所帮助。以下是当我在Petite Chez Scheme中使用
trace define
simple
append
打开跟踪运行代码时显示的内容:

> (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)
调用包装到
列表中来修复它:

(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>
>(简单的“(1233)”)
|(简单(1233)()
|(附()(1))
| (1)
|(简单(23)(1))
|(附(1)(2))
| (1 2)
|(简单(3)(1)(2))
|(附(1)(2)(3))
| (1 2 3)
|(简单()(1 2 3))
成功|#

您发布的代码的问题不在于方案将过程与列表混淆;问题在于调用
append

在调试时跟踪过程的执行可能会有所帮助。以下是当我在Petite Chez Scheme中使用
trace define
simple
append
打开跟踪运行代码时显示的内容:

> (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)
调用包装到
列表中来修复它:

(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>
>(简单的“(1233)”)
|(简单(1233)()
|(附()(1))
| (1)
|(简单(23)(1))
|(附(1)(2))
| (1 2)
|(简单(3)(1)(2))
|(附(1)(2)(3))
| (1 2 3)
|(简单()(1 2 3))
成功|#

apply
quote
到参数apply
quote
到参数