在lisp中展平列表

时间:2012-11-01 06:17:49

标签: list lisp flatten

所以我一直在考虑在lisp中展平列表。

但是,我想要做的是逐级压缩列表。

所以没有

(flatten '(a (b (d (g f))) e)) = (a b d g f e)

我想要

(flatten '(a (b (d (g f))) e)) = (a b (d (g f )) e )

关于如何做这些人的任何想法?

非常感谢=)

2 个答案:

答案 0 :(得分:5)

你可以这样做,例如:

(defun fletten-level (tree)
  (loop for e in tree
        nconc
        (if (consp e)
            (copy-list e)
          (list e))))

(fletten-level '(a (b (d (g f))) e))
;; (A B (D (G F)) E)

这将遍历原始树顶级分支并创建一个新列表,其中包含分支是否为叶子,该叶子,以及分支是否有另外两个分支,然后是第一个叶子和其余分支。

编辑:对不起,第一次实际上并不好,现在应该修复。

EDIT2:因为我自己几乎感到困惑。 (cons (car e) (cdr e))看起来有点奇怪,因为它与仅仅说e基本相同。但是,我意识到nconc将破坏性地修改conses,所以它必须是这样的(即创建一个新的cons单元来连接而不是重用旧的。)

EDIT3:哇......实际上,它必须是copy-list,因为它会以这种方式修改原始列表。

答案 1 :(得分:3)

继续我对非破坏性版本的快速和肮脏的看法:

(defun flatten-level (tree)
  (cond ((null tree) ())
        ((consp (car tree)) (concatenate 'list (car tree) 
                                         (flatten-level (cdr tree))))
        (t (cons (car tree) (flatten-level (cdr tree))))))

这是一个递归函数,它遍历树和每个元素,如果它是一个cons'ed元素,它将它连接到树的其余部分,展平。