提取列表中的每个数字并重建列表?

时间:2009-09-25 12:50:38

标签: list scheme

我需要创建这个函数flat,它应该从输入列表中重新收缩一个新列表(但是在这里,输入列表里面可以有一个嵌套列表):

离。 (A(B(C)D)A)的平坦是(A B C D A)

我的算法如下,不确定它是否正确:

  1. 检查列表是否为空:如果没有,请继续;如果是,则完成 - 返回空列表
  2. 如果列表的长度为1,则完成 - 返回列表
  3. 如果列表长度超过1,我现在该怎么办? (我可以使用carcdr来提取列表,但在任何一种情况下,如何使其递归提取列表到最后,我正在考虑使用append重新构造列出之后。)
  4. 任何帮助/提示都将不胜感激。

2 个答案:

答案 0 :(得分:2)

提示是,如果列表不是null?,则不应该关注传递给flat的列表的长度,而是检查是否{{1列表本身就是一个列表或只是一个原子。如果它本身就是一个列表,你想要展平它,以及展平列表的car

编辑那么,请考虑在两种不同的情况下会发生什么,一种是您使用cdr而一种是cons

append

在第一种情况下,你得到一个平面列表,在第二种情况下,你没有得到一个平面列表。然后你可以尝试

(append '(a b c) '(d e f)) => (a b c d e f)

(cons '(a b c) '(d e f)) => '((a b c) d e f)

但如果(define (bad-flatten lst) (if ((null? lst) '() (append (car (flatten lst)) (cdr (flatten lst))))) car不是列表,则无效。您需要第三种情况,使用lst,如下所示:

cond

答案 1 :(得分:0)

可能不是最优化的解决方案。可能你可以进一步改进它:

(define (list-flatten lst)
  (if (not (null? lst))
      (let loop ((args lst) (ret (list)) (c null))
         (if (not (null? args))
           (begin
             (set! c (car args))
             (cond ((list? c) (loop (cdr args) (append ret (list-flatten c)) c))
             (else (loop (cdr args) (append ret (list c)) c))))
           ret))
       #f))