在球拍中找到列表的深度

时间:2017-11-02 00:46:01

标签: 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 n))
                   (recurse (cdr lst) n))))))

这样可以正常工作,但它会将深度作为包含结果而不是数字的列表返回。例如,当我运行(depth '(((a))))时,它会返回(3)而不只是3

1 个答案:

答案 0 :(得分:1)

嗯,最简单的答案就是在car表单上调用let。这就是看起来的样子(我已经冒昧地重新格式化你的代码并修复了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上的 IE: >hello world Output: he ll ow or ld ,以获取它的第一个元素,并为该结果添加一个。

希望有所帮助!