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

时间:2015-10-03 12:04:34

标签: list recursion functional-programming append 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条件显示了applist,它返回一个空列表。

2 个答案:

答案 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)))