6

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

4

3 回答 3

3

这是我的解决方案,使用与 OP 类似的方法。(在多个最深的项目的情况下,它们都被返回。)

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

(define (deepest lst)
  (let ((filtered (filter pair? lst)))
    (cond ((null? filtered) lst)
          (else (deepest (concatenate filtered))))))
于 2011-01-13T20:24:27.913 回答
2

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

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

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

于 2011-01-13T16:48:10.507 回答
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))))
于 2011-01-13T20:28:48.270 回答