【发布时间】:2020-03-23 22:50:24
【问题描述】:
我有一棵树作为嵌套列表:
(A (B (C (D word) (E word))) (F (G word)))
当子树有一个子树时,我想合并节点,格式为 Parent+Child,所以结果是:
(A (B+C (D word) (E word)) (F+G word))
我目前正在使用递归函数来处理树。我试过了
(defun my-func (tree)
(cond
; base case
((null tree) nil)
; subtree has one child
((and (atom (car tree)) (listp (car(cdr tree))) (= (length (cdr tree)) 1))
(my-func (cdr tree)))
; first element is atom
((atom (car tree)) (cons (car tree) (my-func (cdr tree))))
; else
(t (cons (my-func (car tree)) (my-func (cdr tree)))))
)
我的输入是:("A" ("B" ("C" ("D" "word1") ("E" "word2"))) ("F" ("G" "word3")))
输出为:("A" (("C" ("D" "word1") ("E" "word2"))) (("G" "word3")))
我已经接近了,但我现在的问题是:
为什么我在子列表 (("C" ("D" "word1") ("E" "word2"))) 和 (("G" "word3")) 周围有多余的括号?
另外,我还在为获得“父母+孩子”的符号而苦苦挣扎
【问题讨论】:
-
您在问题中显示的表达式不等于递归函数。
-
提示:编写您的代码,使其返回一个全新的对象(整个树),与旧对象相比,该对象具有您想要的转换。不要改变单个单元格(即不要替换任何
car或cdr的值)。缺点细胞结构的突变是给自己带来问题的好方法,这些问题会让你拔出头发。即使你调试它,你仍然会留下一个破坏其输入完整性的函数,这使得它更难使用。 -
感谢您的帮助。我编辑了我的代码以显示完整的功能。因此,我尝试通过递归树并在向上的过程中使用 cons 构建列表来采用您的提示。这就是您返回一个新对象而不是执行 (setf (car tree) value) 的意思吗?
标签: recursion lisp common-lisp nested-lists