【问题标题】:Appending Elements to an Existing List in Scheme将元素附加到 Scheme 中的现有列表
【发布时间】:2015-12-31 13:26:02
【问题描述】:

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

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

 >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 没有做我需要做的事情,但是是否有类似的功能可以将每个读入元素附加到预先存在的列表中?

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

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

【问题讨论】:

    标签: list recursion functional-programming append scheme


    【解决方案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)))
    

    【讨论】:

      【解决方案2】:

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

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

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

      另外,请注意append 不会修改初始列表,它会创建一个新列表,如果您需要引用它,则必须将其存储在某个地方(这就是我要做@987654325 的原因@ 以上)。

      你的逻辑有更严重的错误。条件的顺序错误(在询问是否为零之前,您必须测试输入是否为数字),如果输入的不是数字,您忘记循环。此外,如果我们将列表作为参数传递给循环,我们就不必做丑陋的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)))))))
      

      如 cmets 中所述,请记住,在循环内的列表末尾附加通常是一个坏主意。可以用于学习目的,但在实际代码中,cons 位于列表的开头,reverse 位于列表的末尾 - 这样更有效。

      【讨论】:

      • 如果我在 applist 周围没有括号,我会收到抛出错误,因为 inpt 和 applist 不在同一时间,或者其中至少一个被称为
      • 所以换句话说,当我调用变量或列表时,我一直无法准确理解我正在转换的内容,我收到了 的这个错误它列出或阅读或你有什么,这是由于过度的括号吗?我在那里做错了什么?
      • @James 我用正确的解决方案更新了我的答案,但是您必须花更多时间阅读教程和文档,您仍然无法理解一些基本概念。
      • 你会推荐什么教程?
      • @ÓscarLópez 提一下在循环中使用(append lst (list x)) 通常是一种反模式可能是个好主意,而更好的模式是在循环中使用(cons x lst) 并在之后反转.
      猜你喜欢
      • 1970-01-01
      • 2021-01-01
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 1970-01-01
      • 2014-06-10
      • 1970-01-01
      相关资源
      最近更新 更多