方案:带有列表追加的递归 [英] Scheme: Recursion with list append

查看:67
本文介绍了方案:带有列表追加的递归的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个递归函数,它基本上保持递归地将元素追加到列表中,直到满足条件为止.但是有一个问题,那就是使用append,我们必须给它一个引用列表.这样做

I have a recursive function that basically keeps appending elements to a list recursively until a condition has been met. There's an issue though, and that's to use append, we must give it a quoted list. So doing

 (append (1 2) 3)

给我们一个错误.

问题是当我第一次将一个列表传递给参数时,我可以把 ' 放在一个带引号的列表中.但是,一旦我将某些内容附加到该列表并再次递归传递给同一个函数,第二次 append 尝试工作时,它将看到该列表不再被引用,因此 Scheme 认为这是一个程序而不是列表.让我向您展示代码的简化版本:

The problem is when I first pass a list to the argument, I can put the ' to make it a quoted list. However, once I append something to that list and it gets recursively passed to the same function again, the second time append tries to work, it will see the list is no longer quoted, so Scheme thinks it's a procedure rather than a list. Let me show you a simplified version of the code:

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

我们通过执行(simple '(1 2 3) '())我意识到上面的程序没用;这只是为了证明我在说什么.

We run the function by doing (simple '(1 2 3) '()) I realize the program above is useless; it's just to demonstrate what I'm saying.

谢谢!

推荐答案

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

The trouble with the code you posted isn't that Scheme is confusing a procedure with a list; the trouble is with the call to append.

在调试时跟踪过程的执行会很有帮助.以下是我在为 simpleappend 打开跟踪的情况下运行代码时显示的内容,在 Petite Chez Scheme 中使用 trace-define:

It can be helpful to trace the execution of a procedure when debugging. Here's what's shown when I run your code with tracing turned on for simple and append, using trace-define in Petite Chez Scheme:

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

因为(append()1)返回1,在第一次递归调用simple时,第二个参数是1 而不是列表.因此,您在下一次调用 append 时会遇到错误.

Because (append () 1) returns 1, in the first recursive call to simple, the second argument is 1 rather than a list. So, you get an error on the next call to append.

您可以通过将 (car x) 调用包装在对 list 的调用中来修复它:

You could fix it by wrapping your (car x) call in a call to list:

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

这是运行的固定版本的跟踪:

Here's a trace of the fixed version running:

> (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>

这篇关于方案:带有列表追加的递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆