区分 Common Lisp 中的列表和原子

发布于 2024-09-30 21:21:54 字数 1171 浏览 10 评论 0原文

我正在制作一个基本的 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)

I have a basic clisp function that I am making that just returns the number of atoms in a list. The issue I am having is I need it to increment for atoms in a list that is in the list, instead of seeing a list as 1 element in the list.

The real question I guess is how do you differentiate in your code whether an element is a list or an atom? If I can do that, I can send the lists to another function to add up and return the number of atoms they contain.

Clear as mud? :)

I have an example here:

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

This works great if there are no embedded lists in the parent list, for example,
'(1 2 3 (4 5) 6) would return 5. I need it to include 4 and 5 instead of the list (4 5) as one.

Thanks for your help.

Jon


EDIT:

(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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相守太难 2024-10-07 21:21:54

如果 foo 是一个列表,(listp foo) 将返回 t,否则返回 nil

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

((listp (car a)) (+ (list_length (car a)) (list_length (cdr a))))

(listp foo) will return t if foo is a list and nil otherwise.

So you can make your list_length function handle nested lists by adding the following case to your cond:

((listp (car a)) (+ (list_length (car a)) (list_length (cdr a))))
陌上青苔 2024-10-07 21:21:54

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。

ATOM is the predicate you are asking for.

I recommend using FLATTEN, a standard routine to flatten lists in lists - I present one implementation here.

(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 returns a list: you can run LENGTH on the list to see how many ATOMS you wound up with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文