查找树中的最大子节点数

时间:2011-01-14 20:50:20

标签: lisp common-lisp

首先,我应该明确指出这是学术项目所必需的。我试图使用Common Lisp找到树中任何节点的最大子节点数。

我现在的代码如下所示 - 我不是百分之百的逻辑,但我认为它应该有效,但它没有给我所需的结果。

(defun breadth (list y)
  (setf l y)
        (mapcar #'(lambda (element) 
              (when (listp element) 
         (when (> (breadth element (length element)) l) 
             (setf l (breadth element (length element)))
           ))) list)

l)

(defun max-breadth(list)
  (breadth list (length list))
  )

举个例子,运行

(max-breadth '(a ( (b (c d)) e) (f g (h i) j)))

应该返回4.

编辑: 跟踪结果和实际返回值,忘记了这些:

CG-USER(13): (max-breadth '(a ( (b (c d)) e) (f g (h i) j)))
 0[6]: (BREADTH (A ((B (C D)) E) (F G (H I) J)) 3)
   1[6]: (BREADTH ((B (C D)) E) 2)
     2[6]: (BREADTH (B (C D)) 2)
       3[6]: (BREADTH (C D) 2)
       3[6]: returned 2
     2[6]: returned 2
   1[6]: returned 2
   1[6]: (BREADTH (F G (H I) J) 4)
     2[6]: (BREADTH (H I) 2)
     2[6]: returned 2
   1[6]: returned 2
 0[6]: returned 2
2

有没有人知道我哪里出错了?我怀疑它与第二个条件有关,但我不确定。

3 个答案:

答案 0 :(得分:4)

首先,标准格式:

(defun breadth (list y)
  (setf l y)
  (mapcar #'(lambda (element) 
              (when (listp element) 
                (when (> (breadth element (length element)) l) 
                  (setf l (breadth element (length element))))))
          list)
  l)

(defun max-breadth (list)
  (breadth list (length list)))

您的问题是(setf l y),它会向您发出有关l未定义的警告。 {@ 1}}不应用于未绑定的变量。使用Setf制作词汇范围:

let

然后,使用单个(defun breadth (list y) (let ((l y)) (mapcar #'(lambda (element) (when (listp element) (when (> (breadth element (length element)) l) (setf l (breadth element (length element)))))) list) l)) 而不是两个嵌套when

and

我在这里找到 (when (and (listp element) (> (breadth element (length element)) 1)) (setf l (breadth element (length element)))) 更简洁:

dolist

参数 (dolist (element list) (when (and (listp element) (> (breadth element (length element)) l)) (setf l (breadth element (length element))))) 始终是参数y的长度,因此可以简化此调用。您也不需要别名list

y

您可以通过(defun breadth (list &aux (y (length list))) (dolist (element list) (when (and (listp element) (> (breadth element) y)) (setf y (breadth element)))) y) 删除双递归调用,但我们可以在此处使用let

max

你也可以使用(defun breadth (list &aux (y (length list))) (dolist (element list) (when (listp element) (setf y (max y (breadth element))))) y)

reduce

答案 1 :(得分:3)

L不是局部变量,因此函数将返回分配给它的最后一个值(即最后一个子树的宽度)。

使用LET声明局部变量:

(LET ((l y))
    ...
)

答案 2 :(得分:0)