我想生成最长子列表的长度。例如,对于列表(1 (2 (3 (4 5)) (6 7) 8) 9)
,由于子列表(2 (3 (4 5)) (6 7) 8)
的长度为4,结果将为4。
我尝试这样做:
(defun len(l)
(cond
((null l) 0)
((atom l) 1)
(t (+ (len(cdr l)) 1))
)
)
(defun lun(l)
(cond
((atom l) 1)
(t(apply #'max (mapcar #' len l)))
)
)
对于上面的示例,它返回4,但是问题在于它仅分析子列表的第一级。如果我尝试为列表(1 (2 (3 (4 5 a a a a)) (6 7) 8) 9)
解析它,即使由于列表(4 5 a a a a)
而应为6,但它也返回4,但它仍然只接受列表(2 (3 (4 5 a a a a)) (6 7) 8)
。
谢谢。
答案 0 :(得分:4)
您的输入是列表(例如,树)列表的列表。 您要计算构成树的列表之一的最长长度。粗略地说,您需要遍历子树,计算它们各自的最长长度,然后将这些长度合并为一个新的最大长度。
基于LOOP宏,该函数的第一个草图如下(您仍然需要做一些工作才能将其转换为完全递归的解决方案):
(defun longest-length (tree)
(loop for subtree in tree maximize (longest-length subtree)))
如上所述,您将问题分为多个子问题,通过查找来递归解决它们 每个子树的最长长度,并通过返回 每个局部最大值的最大值。
但是以上内容缺少一些内容。首先,您需要考虑到应该计算树的长度:
(defun longest-length (tree)
(max (length tree)
(loop for subtree in tree maximize (longest-length subtree))))
此外,当代码到达非约束单元时,代码也会失败。 现在,您必须为树不是约束单元的基本情况添加代码。特别是,nil被视为一个空列表,而不是一个符号:
(defun longest-length (tree)
(typecase tree
(cons (max (length tree)
(loop
for subtree in tree
maximize (longest-length subtree))))
(null 0)
(t 1)))
这是一个测试:
CL-USER> (longest-length '(1 (2 (3 (4 5 a a a a)) (6 7) 8) 9))
6
还考虑使用reduce
,与apply
不同的是,call-argument-limit
对列表((reduce #'max (mapcar ... tree) :initial-value (length tree))
)中的元素数没有限制:
find_all()