【发布时间】:2014-07-12 19:43:23
【问题描述】:
如何将平面列表转换为任意复杂的树状结构?首先,一个简单的例子,将'(1 2 3 4)转换成'(1 (2 (3 (4))))。我知道如何使用经典递归:
(defun nestify (xs)
(if (null xs)
(list)
(list (car xs) (nestify (cdr xs)))))
现在,如果嵌套结构任意复杂怎么办?例如,我想将'(1 2 3 4 5 6 7 8) 转换为'(1 (2 3) (4 (5 6) 7) 8)。我怎样才能编写一个能够在任何此类嵌套结构中转换平面列表的通用函数?我可以考虑提供一个带有虚拟值的模板。例如:
* (nestify '(1 2 3 4 5 6 7 8) '(t (t t) (t (t t) t) t))
'(1 (2 3) (4 (5 6) 7) 8)
我第一次尝试使用递归和自定义树大小查找功能:
(defun length* (tr)
"Count number of elements in a tree."
(cond ((null tr) 0)
((atom tr) 1)
(t (+ (length* (car tr))
(length* (cdr tr))))))
(defun tree-substitute (xs tpl)
"(tree-substitute '(1 2 3) '(t (t) t)) -> '(1 (2) 3)"
(cond ((null tpl) nil)
((atom (car tpl))
(cons (car xs) (tree (cdr xs) (cdr tpl))))
(t (cons (tree xs (car tpl))
(tree (nthcdr (length* (car tpl)) xs) (cdr tpl))))))
有什么方法可以更好、更优雅、更简洁地做到这一点?例如,将列表转换为树的函数可能不会使用模板,尽管我想不出方法。我可以抽象出递归和其他细节并拥有一个简洁的reduce 或其他一些高级函数吗?
【问题讨论】:
标签: lisp common-lisp