我正在尝试制作一个程序,告诉我列表的深度。 这就是我到目前为止所做的:
(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
。
答案 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
,以获取它的第一个元素,并为该结果添加一个。
希望有所帮助!