【问题标题】:Find the most nested list inside a list in Common Lisp在 Common Lisp 的列表中查找嵌套最多的列表
【发布时间】:2011-01-13 16:39:53
【问题描述】:

我是 Common Lisp 和函数式编程的新手,但我在 C、C++、C#、Java 等语言方面拥有丰富的经验。我无法在列表中找到最嵌套的列表。我的输入是这样的:

(0 1 (2 3) 4 (5 (6 (7) 8)) 9)

我想在这个列表中得到嵌套最多的列表,在这种情况下是

(7)

我确实有一个想法,我可以以某种方式展平列表,直到只剩下一个子列表。为了说明我的意思,这里有几个步骤:

第 1 步 - 输入:

(0 1 (2 3) 4 (5 (6 (7) 8)) 9)

第 2 步 - 在“第一层”上展平:

(0 1 2 3 4 5 (6 (7) 8) 9)

第 3 步 - 在“第二层”上展平:

(0 1 2 3 4 5 6 (7) 8 9)

现在只剩下一个嵌套列表,这意味着这是嵌套最多的列表。但是我在这里看到了一个问题,当出现两个或更多这样的列表时。请分享您对此的看法。

我在将这个过程在 Common Lisp 中变为现实时遇到了问题,所以我会很感激一些正确方向的指针,也许是一些示例代码等等。这是一个家庭作业,所以我真的不期待一个完整的解决方案,但如果有人指出一个更简单、更好的解决方案及其实施,我会很高兴。

【问题讨论】:

  • 一个有趣的问题。我想我会做一个 DFS 遍历,并在列表中记录对(叶子,叶子深度),然后在堆栈中搜索具有最大深度的叶子。

标签: lisp common-lisp nested-lists


【解决方案1】:

这是我的解决方案,使用与 OP 类似的方法。 (如果有多个最深的项目,则全部返回。)

我是用 Scheme 编写的,它可能不会立即翻译成 Common Lisp,所以我不觉得它是一个完整的赠品。尽管如此,它仍有可能被剧透,因此请谨慎行事。

(define (deepest lst)
  (let ((filtered (filter pair? lst)))
    (cond ((null? filtered) lst)
          (else (deepest (concatenate filtered))))))

【讨论】:

  • 感谢您的评论。您的回答对我帮助很大,尽管它在 Scheme 中。但是,我从严的回答中学到了更多。如果可以的话,我会给你们两个都接受的答案,但由于他是新来的,而且他的回答对我有更多帮助,所以我选择他的回答作为接受。
  • 这是一个非常优雅的解决方案。
  • 这个解决方案的问题是,“在有多个最深项目的情况下”它不会返回这些最深项目的列表,而是这些列表的串联。
【解决方案2】:

这是我在 CL 中的(不是很干净的)解决方案:

(defun deepest-list (lst)
  (let ((max-depth 0) ret)
    (labels ((inner-deepest-lst (lst depth)
           (cond
         ((null lst) depth)
         ((listp (car lst))
          (let ((local-max (max
                    (inner-deepest-lst (first lst) (1+ depth))
                    (inner-deepest-lst (rest lst)  (1+ depth)))))
            (and (> local-max max-depth) (setf ret (first lst) max-depth local-max))
            local-max))
         (t (inner-deepest-lst (rest lst) depth)))))
      (inner-deepest-lst lst 1))
    ret))

编辑:

再想一想,这是一个稍微干净的解决方案:

(defun deepest-list (lst)
  (labels ((dl (lst depth)
         (cond
           ((atom lst) (cons 0 lst))
           ((every #'atom lst) (cons depth lst))
           (t (funcall (lambda (x y) (if (> (car x) (car y)) x y))
               (dl (car lst) (1+ depth))
               (dl (cdr lst) depth))))))
    (rest (dl lst 0))))

【讨论】:

  • 感谢您的评论。尽管我会很感激一些想法,但您提供了一个可行的解决方案。通过花一些时间并将其分解,我设法从中学到了很多东西。看到你的解决方案并试图理解它真的让我想到了正确的方向。因此,我给你这个问题的公认答案。
  • 仅供参考,我添加了更清洁的解决方案。
【解决方案3】:

您的迭代扁平化列表的方法应该可以正常工作,尽管它不是最有效或(主观上)优雅的方法。

如果有多个这样的列表,正确的输出将取决于规范 - 您应该返回所有列表,还是只返回第一个,或者抛出错误?

如果我是你,我会考虑提出一个递归函数来解决问题。每个级别的递归基本上都会处理给定级别的嵌套列表的元素。想想每个递归调用应该做什么——如果点击一次就很简单了!

【讨论】:

  • 感谢您的评论。是的,我想我应该开始递归思考一下。
猜你喜欢
  • 2021-12-25
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
相关资源
最近更新 更多