我需要一些帮助来理解如何将数字附加到列表中的语法,我通过控制台从用户输入执行此操作,因此必须以递归方式输入这些元素。因此,对于输入的任何数字,列表必须增加每个元素(仅限数字)。
这是我正在使用的代码,问题在于第二个条件。现在它可以工作,但只创建我输入的每个数字的空列表,因此结果将是
>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条件显示了applist,它返回一个空列表。
答案 0 :(得分:1)
在循环时将元素附加到列表末尾的简单方法是调用append
并在之后更新对列表的引用:
(set! applist (append applist (list inpt)))
请注意,您有几个错位的括号 - 在您的代码中有些丢失,有些是不必要的。在方案()
中意味着功能应用程序,你必须小心放置这些括号。
另外,请注意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
位于最后 - 这样效率更高。
答案 1 :(得分:1)
注意(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之前将元素放入一个列表中:
> (append '(1 2 3) (list 4))
'(1 2 3 4)
cons-to-back
的替代定义:
(define (cons-to-back x xs)
(append xs (list x)))