【问题标题】:Scheme - Adding a list to a list of lists?方案 - 将列表添加到列表列表中?
【发布时间】:2018-01-13 07:40:39
【问题描述】:

我正在尝试回答一个方案问题,对于这个问题的一部分,我必须列出一个列表:

(define (join a b (result '()))
  (cons (list a b) result))

所以我接收两个字符,并将它们放在一个列表中,然后我需要将每个子列表放入一个列表列表中,这个函数每次都用两个字符递归调用,所以它应该像这个:

join 1 4
=> ((1 4))
join 2 5
=> ((1 4) (2 5))
join 3 6
=> ((1 4) (2 5) (3 6))

但是,我得到((3 6) (2 5) (1 4)),所以需要反转元素,我尝试将我的cons 函数反转为(cons result (list a b)),但后来我得到(((() 1 4) 2 5) 3 6),我怎样才能以正确的方式获得列表,还是有更简单的方法来做我正在做的事情?

【问题讨论】:

标签: scheme


【解决方案1】:

如果您需要在列表的末尾添加元素,请使用appendcons 用于在 head 处添加元素。试试这个:

(define (join a b (result '()))
  (append result (list (list a b))))

注意append 合并两个列表,这就是为什么我们必须将新元素包围在它自己的list 中。此外,在末尾添加元素也不是一个好主意,使用 append 比使用 cons 更昂贵 - 如果可能,重新考虑您的算法以在头部添加元素,并在末尾反转结果。

【讨论】:

    【解决方案2】:

    这很容易做到:

    (define (group-by-2 lst)
      (let loop ((lst lst) (rlst '()))
        (if (or (null? lst) (null? (cdr lst)))
            (rcons->cons rlst)
            (loop (cdr lst) 
                  (rcons (list (car lst)
                               (cadr lst))
                          rlst)))))
    
    (group-by-2 '(1 2 3 4 5 6 7 8))
    ; ==> ((1 2) (2 3) (3 4) (4 5) (5 6) (6 7) (7 8))
    

    现在rconscons 类似,但它是一个反向列表。 (rcons 1 (rcons 2 (rcons 3))) ; ==> {3 2 1} 但它不是列表,因此您必须将其转换为列表 (rcons->list (rcons 1 (rcons 2 (rcons 3))) ; ==> (3 2 1)

    神奇的功能真的没那么神奇:

    (define rcons cons)
    (define rcons->cons reverse)
    

    所以实际上我并没有必要做那种抽象,但希望我能表达我的意思。您如何组织程序中的中间数据结构并不重要,所以为什么不为您正在做的工作做最好的事情。对于列表,最好从头到尾进行迭代并从头到尾进行迭代。每个元素每个插入 O(1),最后你做一个 O(n) 反转。它胜过 append n 次,这将使它成为 O(n²)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 2017-02-20
      相关资源
      最近更新 更多