我对计划和汽车,cdr等的想法很新。我有这个函数来返回列表的最后一个元素,但是现在它只返回一个空列表。
(define (last mylist)
(if (list? mylist)
(if (null? mylist)
(if (null? (cdr mylist))
'()
(last (cdr mylist))
)
)
)
)
答案 0 :(得分:2)
本书How To Design Programs通过为您提供具体而详细的设计方案,帮助您解决这个问题。第9.2节“非空列表”中介绍了这个特殊问题。从广义上讲,以下是您需要遵循的步骤:
答案 1 :(得分:2)
仅凭你的缩进,很明显你是从另一种编程语言来到Scheme
但您也错误地使用if
- 在Scheme中,您不能拥有单分支 if
语句。嗯,在Scheme中根本没有语句,只有表达式,而if
表达式总是需要3个操作数(参数)
你的节目很接近。只需稍加调整就可以了解您需要的位置 - 请注意缩进如何让您轻松查看if
的3个操作数。
(define (last mylist)
(if (null? mylist)
#f
(if (null? (cdr mylist))
(car mylist)
(last (cdr mylist)))))
最后,Scheme提供cond
,有助于防止条件序列不必要的代码嵌套
(define (last mylist)
(cond ((null? mylist)
#f)
((null? (cdr mylist))
(car mylist))
(else
(last (cdr mylist)))))
(last '())
;; #f
(last '(1))
;; 1
(last '(1 2))
;; 2
(last '(1 2 3))
;; 3
超出这个答案的范围是#f
的返回值(last '())
- 我认为在空列表上调用last
应该具有调用{{1}的相同效果在一个空列表上。但是我会把它留给你。
答案 2 :(得分:1)
如果(null? mylist)
不成立,那是什么?非空列表。
非空列表可能包含一个或多个元素。
有多少元素有这样的列表,它们的最后一个元素是它们的第一个?
关于此类列表可以说什么? cdr
?您应该使用它来提前停止递归。现在它一直持续到列表为空,但你需要提前停止。
(define (last mylist)
(if (list? mylist)
(if (null? mylist)
'()
;; {1}
(last (cdr mylist))
;;
)))
在{1}
,您无条件致电(last (cdr mylist))
。但是,如果你已经到达列表的末尾怎么办?如果只剩下一个元素怎么办?在这种情况下,您需要返回 it 作为结果。因此,用if
表达式替换无条件代码来完成此任务。
答案 3 :(得分:1)
当您提出问题(null? (cdr mylist))
时,如果该问题是真的而不是(car mylist)
,则应该返回'()
。从那时起,它意味着mylist
是单原子列表。
(define (last mylist)
(cond ((null? mylist) '())
((null? (cdr mylist)) (car mylist))
(else (last (cdr mylist)))))
您可以使用cond
代替if
来避免嵌套条件,因为cond
处理多个手臂,而if
通常用于当您只有两个选项时条件。
这本书the Little Schemer最能帮助我想象一下Scheme计划中发生了什么。
答案 4 :(得分:0)
我认为这最接近您的初始代码:
(define (last mylist)
(if (list? mylist)
(if (null? mylist)
'() ; input list is empty
(if (null? (cdr mylist))
(car mylist) ; list only has one remaining element so this is it
(last (cdr mylist)))) ; otherwise, recurse
#f)) ; input is not a list
使用if
时,请务必同时填写 true 和 false 分支。