方案列表总是以相反的顺序

Mat*_*att 2 recursion scheme list r5rs

对于大多数更先进的阴谋者来说可能是一个微不足道的问题,但作为一个新手,我发现这是一个问题.

我需要一种方法来构建一个新的列表,其顺序与它进入时的顺序相同.例如,假设我们有一个列表'(1 2 0 3 4 0 0 5).但是遍历列表并将cdr传回,因为第一个参数最终会向后构建新列表.

这是代码中的一个例子:

我传递了一个需要完成工作的"旧列表"和一个空列表作为"新列表"形成并返回.

注意,将0取出仅仅是新列表必须满足的"某些条件"

  (define (form-new-list old-list new-list)
    (cond ((null? old-list) new-list)
          (else
           (if (eq? (car old-list) 0) (form-new-list (cdr old-list) new-list)
               (form-new-list (cdr old-list) (cons (car old-list) new-list))))))

  ;test
  (form-new-list '(1 2 0 3 4 0 0 5) '()) ; gives (5 4 3 2 1)
  ;but want (1 2 3 4 5)
Run Code Online (Sandbox Code Playgroud)

我不只是想反转使用反向过程返回的列表,而是希望首先以正确的顺序将新列表放在一起.

是否有某种"技巧",就像在其他地方进行递归调用一样?

任何意见是极大的赞赏.

Ósc*_*pez 5

您正在寻找使用递归遍历列表的自然方式.使用此过程作为解决方案的模板 - 它只是完全按照收到的方式复制列表:

(define (copy lst)
  (if (null? lst)
      '()
      (cons (car lst)
            (copy (cdr lst)))))
Run Code Online (Sandbox Code Playgroud)

请注意以下几点:

  • 当输入列表为空时递归结束,并且假设我们正在构建新列表,则返回的正确值是空列表
  • 我们有兴趣构建一个新的列表,我们通过cons输出列表的新元素来实现,在这种情况下恰好是输入列表的第一个元素(它的car部分)
  • 最后,通过使用输入列表的其余cdr部分(其部分)调用过程来推进递归步骤

像往常一样,我最后通过推荐你看看The Little Schemer如何设计程序来学习如何以递归方式思考,这两本书将教你如何使用Scheme来解决递归过程.