【问题标题】:Unnesting parentheses?取消嵌套括号?
【发布时间】:2010-11-27 18:54:40
【问题描述】:

我想使用递归函数编写代码来取消列表中的括号。

这是一个例子:

(unnest '(1 (2 (3)) (4 5))) ==> (1 2 3 4 5)

【问题讨论】:

  • 这个函数通常叫做FLATTEN。
  • 在 SICP 书中也称为 fringe - 练习 2.28,第 111 页。
  • 这对我来说是递归的经典时刻。

标签: function recursion lisp


【解决方案1】:
(defun unnest (lst)
  (cond ((null? lst) '())
        ((not (list? lst)) (list lst))
        (t
         (append (unnest (car lst))
                 (unnest (cdr lst))))))

> (unnest '(1 (2 (3)) (4 5))) 
(1 2 3 4 5)

基本上思路如下:

  • 如果您有一个空列表,那么您显然不需要取消嵌套它;
  • 如果它不是一个列表,那么它一定是一个原子,因此您返回一个包含该原子的列表;
  • 在最后一个条件中,您有 一个列表,因此您基本上说:未嵌套列表的结果是附加到列表其余部分的未嵌套版本的第一个元素的未嵌套版本,就是这样,剩下的就是递归了。

希望对你有帮助。

【讨论】:

  • 或者更简单地说,我们正在遍历一棵树并选择叶子节点,然后递归地添加到列表中。避免再次重构树结构的技巧是使用append 函数。
  • 是的,这更简单:P. 顺便说一句,你为什么将t 替换为elseelse 在 Scheme 中使用。
  • 是的,我尝试了 Scheme,我认为 t 是一个错误 :o) 如果你愿意,可以回滚我的编辑。顺便说一句,t 是什么?
  • 当然,没问题。 t 是 LISP 的 true 值;一种在cond 中没有特殊else 案例的廉价方法:)。
猜你喜欢
  • 2021-10-13
  • 2011-01-07
  • 2013-04-21
  • 1970-01-01
  • 2019-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多