首先,我应该明确指出这是学术项目所必需的。我试图使用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
有没有人知道我哪里出错了?我怀疑它与第二个条件有关,但我不确定。
答案 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)