Scheme 在球拍中寻找列表的深度

Scheme 在球拍中寻找列表的深度,scheme,racket,r5rs,Scheme,Racket,R5rs,我试图做一个程序,告诉我列表的深度。 这就是我到目前为止所做的: (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

我试图做一个程序,告诉我列表的深度。 这就是我到目前为止所做的:

(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

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

然而,这并不符合问题的精神。在这种情况下,函数实际上比您想象的工作得更好。它为您提供了顶级列表(包括外部列表)中包含的列表的深度,因此在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
。如果我重新实现
map
并将所有代码放在一个地方,它可能实际上比您的代码更复杂。关键是不要在不需要的时候重新实现,把事情分解成更小、更抽象的部分。我建议你写作时保持开放。
(define (depth-many lst) (+ 1 (map depth lst)))