首页 > 解决方案 > 用于确定列表中嵌套列表长度的 Common Lisp 函数

问题描述

我只被允许使用do我仍然无法掌握的构造,概念。我尝试了以下代码,但它返回nil.

(defun fun(list)
(do ((i 0 (+ i 1)) (l '() (if (listp (nth i list)) (append l (list (length (nth i list)))))))
((null (nth i list)) l)
)
)

更新的值是l错误的吗?此列表的输出(a (b) (c d))应为(1 2).

标签: listlispcommon-lispnested-listsdo-loops

解决方案


试着用列表而不是数组来思考。您正在使用列表的第 n 个元素,就好像它是一个数组一样。相反,do您可以通过每次获取下一个子列表来遍历列表,即删除第一个元素并获取另一个没有该第一个元素的列表。

(defun fun(list)
  (do ((l list (cdr l))
       (result nil) )
      ((null l) (nreverse result))
    (if (listp (car l))
      (push (length (car l)) result) )))

运算符接受三个参数:do变量列表、结束条件和循环体。第一个包括变量的名称、它们的初始值以及(可选)它们如何从一个循环变为下一个循环。例如,(l list (cdr l))假设您使用一个变量l,其初始值为输入列表,并且从一个循环到下一个循环,它将成为自身的 cdr,即它将丢失其第一个元素。结束条件还包括函数的返回值。((null l) (nreverse result))我们说当变量为l空时,函数将结束并返回值(nreverse result)。为什么要逆向?因为我们在 body 中使用 push,它以错误的顺序累积值。最后,body 告诉函数增加result第一个元素的长度l每当这是一个列表。


推荐阅读