最长子列表的LISP长度

时间:2019-01-12 18:51:54

标签: list lisp common-lisp clisp

我想生成最长子列表的长度。例如,对于列表(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)

谢谢。

1 个答案:

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