0

これは99のLisp問題の#7です:リストを変換し、各リストをその要素で(再帰的に)置き換えることにより、リストを要素として保持している可能性があります。私はいくつかの解決策を試しました。たとえば、#2680864またはここからです。それらはすべて機能しますが、引用符で囲まれた要素を含むリストをフラット化すると問題が発生します。例えば:

> '(a 'b c)
(A 'B C)

> '(a (quote b) c)
(A 'B C)

> (flatten '(a 'b c))
(A QUOTE B C)

後者の場合、私は取得したいと思います:

(A 'B C)

'の内部表現がこのタスクの邪魔になるようです!SBCL、CLISP、ECL、...これらはすべて同じように動作します。

4

1 に答える 1

2

リスト内の引用された要素?それは通常意味がありません。なぜあなたはそれを引用してもらうのですか?

(a b c)3つの記号のリストです。なぜリストの要素を引用するのですか?のように(a 'b c)?なんで?見積もりの​​目的は何ですか?

Common Lispは、に展開される'readmacroです。これは通常のリストであるため、通常のフラット化操作では、シンボルがフラットリストに収集されます。これは、flatten関数が通常、何かがアトムであるかどうかをチェックするためです。これが必要ない場合は、flatten関数で、何かがアトムであるか、最初のシンボルが2要素のリストであるかを確認する必要があります。'a(QUOTE A)QUOTEAQUOTE

しかし、上で述べたように、引用符で囲まれた記号は通常リスト内では役に立たないため、デフォルトの使用法は記号を平坦化することです。それ以外の場合は、フラット化関数を拡張する必要があります。

例えば:

(defun flatten (l &key (test #'atom))
  (cond ((null l) nil)
        ((funcall test l) (list l))
        (t (loop for a in l nconc (flatten a :test test)))))


CL-USER > (flatten '(a (('b) c) ('d) )
                   :test (lambda (item)
                           (or (atom item)
                               (and (eq (first item) 'quote)
                                    (null (cddr item))))))

(A (QUOTE B) C (QUOTE D))
于 2012-05-17T17:27:42.123 に答える