在球拍中找到列表的深度

finding the depth of a list in racket

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

(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))))))

这工作正常,但它 returns 深度作为包含结果而不是数字的列表。例如,当我 运行 (depth '(((a)))) 时,它 returns (3) 而不是 3.

嗯,最简单的答案就是在 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 上,以获取它的第一个元素,并将结果加一。

希望对您有所帮助!