5

リスト内のアトムの数を返すだけの基本的なclisp関数を作成しています。私が抱えている問題は、リストをリスト内の1つの要素として表示するのではなく、リスト内のリスト内のアトムをインクリメントする必要があることです。

私が推測する本当の質問は、要素がリストであるかアトムであるかをコードでどのように区別するかです。それができれば、リストを別の関数に送信して、リストに含まれるアトムの数を合計して返すことができます。

泥のように澄んでいますか?:)

ここに例があります:

(defun list_length (a)
  (cond ((null a) 0)
        (t (+ 1 (list_length (cdr a))))))

これは、親リストに埋め込みリストがない場合にうまく機能します。たとえば、 '(1 2 3 (4 5) 6)5が返されます。リスト(4 5)の代わりに4と5を1つとして含める必要があります。

ご協力いただきありがとうございます。

ジョン


編集:

(defun list_length (a)
  (cond ((null a) 0)
        ((listp (car a)) (list_length (car a)))
        (t (+ 1 (list_length (cdr a))))))

[18]> (list_length '(1 2 3 (4 5) 6))
1. Trace: (LIST_LENGTH '(1 2 3 (4 5) 6))
2. Trace: (LIST_LENGTH '(2 3 (4 5) 6))
3. Trace: (LIST_LENGTH '(3 (4 5) 6))
4. Trace: (LIST_LENGTH '((4 5) 6))
5. Trace: (LIST_LENGTH '(4 5))
6. Trace: (LIST_LENGTH '(5))
7. Trace: (LIST_LENGTH 'NIL)
7. Trace: LIST_LENGTH ==> 0
6. Trace: LIST_LENGTH ==> 1
5. Trace: LIST_LENGTH ==> 2
4. Trace: LIST_LENGTH ==> 2
3. Trace: LIST_LENGTH ==> 3
2. Trace: LIST_LENGTH ==> 4
1. Trace: LIST_LENGTH ==> 5
5
[19]> (dribble)
4

2 に答える 2

4

(listp foo)がリストのt場合は戻り、それ以外の場合は戻ります。foonil

したがってlist_length、次のケースを次のように追加することで、関数にネストされたリストを処理させることができますcond

((listp (car a)) (+ (list_length (car a)) (list_length (cdr a))))
于 2010-11-05T00:27:50.633 に答える
3

ATOMはあなたが求めている述語です。

リスト内のリストをフラット化するための標準ルーチンであるFLATTENを使用することをお勧めします。ここでは、1つの実装を紹介します。

(defun flatten (x)
  "descend into the supplied list until an atom is hit.
append the atom to the flattened rest"
  (if (endp x)
      x
    (if (atom (car x ))
    (append (list (car x)) (flatten (cdr x)))
      (append (flatten (car x)) (flatten (cdr x ))))))

Flattenはリストを返します。リストでLENGTHを実行して、終了したATOMSの数を確認できます。

于 2010-11-05T01:15:24.167 に答える