0

だから私は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 )

この人をどうやってやるのかについて何か考えはありますか?

感謝します=)

4

2 に答える 2

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)

これにより、元のツリーの最上位のブランチがループされ、ブランチがリーフであるかどうか、そのリーフ、およびブランチに他の2つのブランチがある場合は、最初のリーフと残りのブランチの両方を含む新しいリストが作成されます。

編集:申し訳ありませんが、実際には初めては良くありませんでしたが、今は修正する必要があります。

EDIT2:私がほとんど混乱したからといって。(cons (car e) (cdr e))基本的にはただ言うのと同じなので、少し奇妙に見えますe。ただし、nconcこれによりconsesが破壊的に変更されることに気付いたので、この方法である必要があります(つまり、古いconsセルを再利用するのではなく、連結する新しいconsセルを作成します)。

EDIT3:うわー...実際にはcopy-list、元のリストをこのように変更するため、そうである必要があります。

于 2012-11-01T08:24:31.290 に答える
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された要素である場合、それをツリーの残りの部分に連結し、平坦化します。

于 2012-11-01T19:25:55.980 に答える