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) 作为一个。

谢谢你的帮助。

乔恩


编辑:

(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如果foo是列表则返回,nil否则返回。

因此,您可以list_length通过将以下案例添加到您的函数来处理嵌套列表cond

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

ATOM是您要求的谓词。

我推荐使用 FLATTEN,这是一种扁平化列表中的列表的标准例程——我在这里展示了一个实现。

(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 回答