Scheme(DrRacket)-cond语句不适用于递归
我正在使用drracketr5rs学习这个方案。我以为我已经确定了概念,但我无法让这个简单的递归练习起作用。我认为这是一个错误,但我不确定 有人能看到这个问题吗?希望能解释一下为什么我的代码不起作用?我真的很想学习这个函数式语言 此代码将正确生成#T和#F:Scheme(DrRacket)-cond语句不适用于递归,scheme,racket,Scheme,Racket,我正在使用drracketr5rs学习这个方案。我以为我已经确定了概念,但我无法让这个简单的递归练习起作用。我认为这是一个错误,但我不确定 有人能看到这个问题吗?希望能解释一下为什么我的代码不起作用?我真的很想学习这个函数式语言 此代码将正确生成#T和#F: (define three (lambda (L target1 target2 target3 sum) (cond ((= target1 0) (three L (car L) (cadr L) (caddr
(define three (lambda (L target1 target2 target3 sum)
(cond
((= target1 0) (three L (car L) (cadr L) (caddr L) 0))
((NULL? L) (= (- sum (+ target1 (+ target2 target3))) (+ target1 (+ target2 target3)))) ; sum minus targets = targets
(else (three (cdr L) target1 target2 target3 (+ sum (car L)))) ; return true if branch returns true
)))
当我用(3’(1 2 3 6)0 0 0 0启动程序时,它返回#T,因为1+2+3=6。当我用(3’(1 2 3 5)0 0 0 0 0)启动程序时,它会从1+2+3开始返回#F=五,
现在,问题来了。我想做多分支递归。但是,此代码每次都返回#T!因为我不能让它返回#F,所以我不能让它跳到递归的下一个分支
(define three (lambda (L target1 target2 target3 sum)
(cond
((= target1 0) (three L (car L) (cadr L) (caddr L) 0))
((NULL? L) (= (- sum (+ target1 (+ target2 target3))) (+ target1 (+ target2 target3)))) ; sum minus targets = targets
((three (cdr L) target1 target2 target3 (+ sum (car L))) #T) ; return true if branch returns true
(else 'hit_the_bottom) ; IT NEVER HITS THIS STATEMENT!
)))
有什么想法吗?解决方案太复杂了,如果您只想检查列表中前三个数字的总和是否等于第四个数字,那么使用更简单的非递归方法会更好:
(define (three lst)
(= (+ (first lst) (second lst) (third lst))
(fourth lst)))
除此之外,你为什么不坚持第一种方法呢?它适用于您,但不清楚“多分支递归”是什么意思,为什么第二种方法需要它?第一种方法不是“多分支”吗?毕竟,它已经在两个部分递归调用three
。关于第二种方法总是返回#t
的原因,这一行:
(else 'hit_the_bottom)
((three (cdr L) target1 target2 target3 (+ sum (car L))) #t)
。。。将确实执行,但由于它是递归调用的一部分,因此将返回到此行:
(else 'hit_the_bottom)
((three (cdr L) target1 target2 target3 (+ sum (car L))) #t)
而到达底部的值'hit_
是#t
,因此整个过程最终将返回#t
。请注意,在方案中,所有非#f
的内容都是#t
,尤其是在这种情况下,'点击底部
将被解释为#t
。为了明确else
部分确实正在执行,运行此代码,您将看到'点击屏幕底部
一次:
(define three
(lambda (L target1 target2 target3 sum)
(cond ((= target1 0)
(three L (car L) (cadr L) (caddr L) 0))
((null? L)
(= (- sum (+ target1 target2 target3))
(+ target1 target2 target3)))
((three (cdr L) target1 target2 target3 (+ sum (car L)))
#t)
(else (display 'hit_the_bottom) 'hit_the_bottom))))
(three '(1 2 3 6) 0 0 0 0)
=> #t
(three '(1 2 3 5) 0 0 0 0)
=> hit_the_bottom #t
最后,要纠正第二种方法,将最后一行替换为
(else#f)
,它将按预期工作。快速回答:将最后一行替换为(else#f)
,它将工作。看看我下面的答案,你给了我一个更有效的选择。然后,你非常好地解释了我的问题,所以我现在完全明白为什么会发生。此外,您提供了一个修复程序,因此我的应用程序现在可以运行,我可以完成其他部分。你太棒了。非常感谢。