方案-附加到列表的末尾

时间:2019-06-28 22:45:40

标签: list append scheme lisp

对于这样一个简单的问题,我感到非常抱歉。这太琐碎了,我一直无法在网上找到与此问题有关的人。因此,我希望获得一些帮助。

我想编写一个非常简单的函数,该函数接受一个列表和一个项目,并将该项目追加到列表的末尾。

我递归编写的函数转到列表的末尾并返回新项。实在令人沮丧,无法正常工作。这是我见过的最简单的功能

(define (my-append lst item)
  (if (null? lst)
    item
    (cons (car lst) (my-append (cdr lst) item))))

(display (my-append (list 1 2 3 4) 5))

显示

(1 2 3 4 . 5) 

我不知道为什么会有那个点,这非常令人沮丧。我以前在任何SO问题中都没有遇到过。

我只想看

(1 2 3 4 5)

我真的很感谢您的帮助,因为对此我感到非常沮丧。如果有帮助,我正在使用在线编译器运行此代码 https://repl.it/languages/scheme

2 个答案:

答案 0 :(得分:3)

您只需要使用 list 而不是项目结束递归即可。代替这个:

(if (null? lst)
    item

执行以下操作:

(if (null? lst)
    (list item)

为了澄清-Scheme中的列表必须以空白列表'()结尾。如果您的递归以某项结尾,那么最终您将得到以下内容:

(cons 4 5)
=> '(4 . 5)

那是一对cons 。正确的列表以空列表结尾:

(cons 4 (cons 5 '()))
=> '(4 5)

与以下相同:

(cons 4 (list 5))
=> '(4 5)

顺便说一下,这是在项目末尾附加项目的惯用方式:

(define (my-append lst item)
  (append lst (list item)))

答案 1 :(得分:3)

.之所以存在,是因为结果列表中的最后一对没有其cdr指向空列表。适当的列表是成对的链,其中链中的最后一个cdr指向一个空列表。例如

(list 1 2 3 4 5)
# is equivalent to
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 '()))))

但是您要创建的列表是

(cons 1 (cons 2 (cons 3 (cons 4 5)))

您在列表中获得.的原因与(cons 4 5)打印为(4 . 5)的原因相同。

编写递归函数时,您需要考虑以下方式:

  1. 输入的基本情况是什么?
  2. 该函数应为该输入返回什么?
  3. 在非基础情况下,如何简化输入以更接近基础?
  4. 如何将递归调用的结果与输入结合起来?

除了步骤2以外,您都没事。

考虑基本情况:

(my-append '() 5)

这应该返回(5),对吧?但是您的函数只会返回5。这意味着您需要在基本情况下将item包装在列表中。

(define (my-append lst item)
  (if (null? lst)
    (list item)
    (cons (car lst) (my-append (cdr lst) item))))

请注意,内置的append过程用于附加两个列表,而不是附加列表和单个项。您的函数是定义该函数的正确方法。