Scheme - 将列表添加到列表列表中?

时间:2018-01-12 16:14:08

标签: scheme

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

@JsonInclude(JsonInclude.Include.NON_ABSENT)

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

(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)),怎么能我以正确的方式获得列表,还是有更简单的方法来做我正在做的事情?

2 个答案:

答案 0 :(得分:3)

如果您需要在列表的 end 添加元素,请使用append; cons用于在 head 添加元素。试试这个:

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

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

答案 1 :(得分:-1)

这可以很容易地完成:

(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²)