【问题标题】:finding the depth of a list in racket在球拍中查找列表的深度
【发布时间】:2017-11-02 00:46:00
【问题描述】:

我正在尝试创建一个程序来告诉我列表的深度。 这是我目前所拥有的:

(define (depth lst)
  (let recurse ((lst lst) (n 1))
    (cond ((null? lst) '())
          ((not (pair? (car lst)))
           (cons n (recurse (cdr lst) n)))
          (else
           (append (recurse (car lst) (+ 1 n))
                   (recurse (cdr lst) n))))))

这很好用,但它以包含结果而不是数字的列表形式返回深度。例如,当我运行(depth '(((a)))) 时,它返回(3) 而不仅仅是3

【问题讨论】:

    标签: scheme racket r5rs


    【解决方案1】:

    嗯,最简单的答案就是在let 表单上致电car。下面是它的样子(我冒昧地重新格式化了您的代码并修复了 depth 函数的阴影):

    (define (depth lst)
      (car (let recurse ((lst lst) (n 1))
             (cond ((null? lst) '())
                   ((not (pair? (car lst)))
                    (cons n (recurse (cdr lst) n)))
                   (else
                    (append (recurse (car lst) (+ 1 n))
                            (recurse (cdr lst) n))))))))
    

    但是,这不符合问题的精神。在这种情况下,该功能实际上比您想象的要好。它为您提供顶级列表中包含的列表的深度(但包括外部列表),因此在 REPL 中与它的交互如下所示:

    > (depth '((((a)))))
    '(4)
    > (depth '((((a))) ((b)) (c)))
    '(4 3 2)
    

    现在,这实际上是非常有用且有趣的行为,但如果这不是您想要的,您将不得不重写整个函数。这就是我要写的方式。请注意,如果我将第一个和第二个组合在一起,cond 可能会少一个手臂,但这是一个偏好问题:

    (define (depth lst)
      (cond
        [(empty? lst) 0]
        [(not (pair? lst)) 0]
        [else (+ 1 (depth (car lst)))]))
    

    请注意,这要短得多,而且您仍然可以通过执行以下操作获得与原始函数相同的结果:

    (define (depth-many lst) (+ 1 (map depth lst)))
    

    无论如何,新的深度函数(depth-prime?)需要一个参数。如果它是空的或非列表项,它在底层,所以它不需要再做任何事情了。否则(意味着它有一个列表参数)它调用 car 在列表中,它本身在 car 中,获取它的第一个元素,并将一个添加到该结果中。

    希望有帮助!

    【讨论】:

    • 你到底是怎么做到这么简单的?????????这是令人兴奋的。再次感谢!
    • 不同之处在于,您的函数包含了在一个地方执行就地深度查找和整个列表的深度查找的所有逻辑,有效地重新实现map in过程。如果我重新实现map 并将所有代码放在一个地方,它实际上可能比您的复杂。关键是永远不要在不必要的时候重新实现,并将事情分解成更小、更抽象的部分。我建议您在写作时保持docs.racket-lang.org/reference/pairs.html 处于打开状态。
    猜你喜欢
    • 2018-03-04
    • 2014-07-09
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多