将元素附加到 Scheme 中的现有列表

Appending Elements to an Existing List in Scheme

我需要一些帮助来理解如何将数字附加到列表中的语法,我是通过控制台从用户输入中执行此操作的,因此必须递归地输入这些元素。因此,对于输入的数字,列表必须随着添加的每个元素(仅数字)而增长。

这是我正在使用的代码,问题在于第二个条件。现在这可行,但只会为我输入的每个数字创建一个空列表,因此结果将是

 >12
 >202
 >30
 ()()()
 zero input: stopping list


(define (inputlist)
(let ((applist list))
(let ((inpt (read)))
  (cond
  ((= inpt 0)(newline) (display "zero input: stopping list"))
  ;;OLD((number? inpt) (cons inpt applist) (display (applist))(inputlist))
  ((number? inpt) (append (applist)(list inpt)) (display (applist))(inputlist))
  (else 
  display "Not a number")))))

我明白为什么 cons 没有做我需要它做的事情,但是是否有类似的功能将每个读入元素附加到预先存在的列表中?

编辑:我已经接近了我需要做的事情,但仍然得到了相同的结果,我现在在我的应用程序列表上附加了一个我通过每个输入创建的列表,尽管它仍然会产生尽可能多的结果我输入时为空列表。

第二次编辑:我已经意识到为什么它打印多个 () 是因为当输入 0 时它被从堆栈中调用,所以我确定它不起作用,因为附加没有按预期工作,我在 0 条件下显示了应用列表,它 returns 一个空列表。

一种在循环时将元素附加到列表末尾的简单方法是调用 append 并随后更新对列表的引用:

(set! applist (append applist (list inpt)))

请注意,您有几个错放的括号 - 在您的代码中,有些括号丢失了,有些是不必要的。在 Scheme 中 () 表示 函数应用程序 ,你必须小心放置这些括号的位置。

此外,请注意 append 不会修改初始列表,它会创建一个新列表,如果您需要引用它,则必须将它存储在某个地方(这就是为什么我在上面做 set!)。

你的逻辑有更严重的错误。条件顺序错误(您必须在询问输入是否为零之前测试输入是否为数字),如果输入的不是数字,您就忘记了循环。此外,如果我们将列表作为参数传递给循环,我们就不必做丑陋的 set!。试试这个,它更接近你的目标:

(define (inputlist)
  (let loop ((applist '()))
    (let ((inpt (read)))
      (cond ((not (number? inpt))
             (display "not a number")
             (newline)
             (loop applist))
            ((zero? inpt)
             (display "zero input: stopping list"))
            (else
             (let ((new-applist (append applist (list inpt))))
               (display new-applist)
               (newline)
               (loop new-applist)))))))

如评论中所述,请记住,在循环内的列表末尾追加通常不是一个好主意。出于学习目的没问题,但在实际代码中,您 cons 位于列表的开头,reverse 位于列表的末尾 - 这样效率更高。

请注意 (cons x xs) 其中 x 是一个元素,xs 是一个列表会生成一个新列表,其中 x 作为其第一个元素。

这是使用 cons 在列表末尾添加元素的一种方法:

示例: 将 4 添加到 (1 2 3) 1. 反转列表:(3 2 1) 2.在前面加4:(4 3 2 1) 3.反转:(1 2 3 4)

> (reverse (cons 4 (reverse (list 1 2 3)))
(1 2 3 4)

利用这个原理的函数:

(define (cons-to-back x xs)
  (reverse (cons x (reverse xs))))

> (cons-to-back 4 (list 1 2 3))
(1 2 3 4)

另一种方法是使用 append 附加两个列表的元素:

> (append '(1 2 3) '(4 5 6))
(1 2 3 4 5 6)

我们需要做的就是在使用追加之前将元素放入列表中:

> (append '(1 2 3) (list 4))
'(1 2 3 4)

cons-to-back 的替代定义:

(define (cons-to-back x xs)
  (append xs (list x)))