逻辑的另一个问题,任务是找到列表的深度,例如:给定一个 (A B (C D (E)))
列表,它应该以某种方式指示深度为2(如果包含基本列表则为3) . 我被限制在一组常见的Racket函数中,我将在下面列出 . 我在哪里,我可以遍历列表,但最终停在第一个子列表,即: (A (B (C)) (D (E (F))))
只出现2 .
以下是可用功能列表:
-
cons,car,cdr,define,quote,if,cond,else
-
算术的基本形式(, - ,*,/)
-
非常基本的测试(null?,list?,eq?,数字比较)
到目前为止,这是我的定义,如果有人能让我朝着正确的方向转变,我真的很感激 .
(define (len l) (if (null? l) 0 (+ 1 (len (cdr l)))))
(define A '(A (B) (C (D))))
(define (depth l) (cond
[(null? l) '()]
[(list? (car l)) (cons (car l) (depth (car l)))]
[else (depth (cdr l))]
))
(depth A)
(len (depth A))
3 回答
这是我在Common Lisp中的定义
我没有在这台电脑上安装Racket,所以这是一个未经测试的Scheme / Racket翻译:
逻辑如下:
如果列表为空,则返回当前深度 .
如果列表的
car
是原子(不是列表),则不会增加深度,找到列表的其余部分(cdr
)的深度 .否则,深度将是
car
的1个深度之间的最大值(记住,现在是列表)和列表的cdr
的深度 . 注意car
的深度增加,而不是cdr
.使用的预定义程序:
+
,max
,null?
,list?
,car
,cdr
,not
.这可以通过简单的折叠实现
foldl
有一个简单的实现这是一些输出
如果您不想使用折叠抽象,则可以在
list-depth
内扩展折叠两者都产生相同的输出,但在此实现中,折叠和最大值这两个概念纠缠在一起 . 与第一个相比,看到折叠的内脏使得阅读这个答案变得更加困难 .
折叠的内脏使得虫子很容易隐藏在最后的片段中 . 我不能建议首先写这种方式,所以我不打算花费精力来修复它 .
每个列表都是在
car
下的当前元素和cdr
下的列表的其余部分构建的 .列表的深度与列表其余部分的深度相同,如果这是最深的 .
如果这是最深的,那么列表的深度比其
car
的深度多一个 .所以,
当然,不要忘记处理列表为空时的情况,或者原子(不是一对 - 你不能用非对参数调用
car
或cdr
,如果你这样做会导致错误) :空列表的深度为零 .
原子的深度为零 .