如何退出Scheme递归函数desplazamiento中的无限循环?
解决Scheme递归函数无限循环问题
原代码
(define (desplazamiento a b c) (cond ((equal? c #t) (begin ((draw-solid-rectangle ventana) (make-posn a b) 40 40 "blue") (sleep 0.5) ((clear-solid-rectangle ventana) (make-posn a b) 40 40 ) (cond ((= b 160) (desplazamiento a b #f)) ) (desplazamiento (+ a 40) (+ b 40) c) )) ((equal? c #f) (begin ((draw-solid-rectangle ventana) (make-posn a b) 40 40 "blue") (sleep 0.5) ((clear-solid-rectangle ventana) (make-posn a b) 40 40 ) (cond ((= b 0) (desplazamiento a b #t)) ) (desplazamiento (+ a 40) ( b 40) c) )) ) ) (desplazamiento 0 0 #t )
问题描述
我编写了上述Scheme递归函数desplazamiento,当前陷入无限循环。我尝试新增条件并定义变量d为true,但将d设为false后仍无法退出循环,请求解决该问题。
问题根源
- 重复递归调用:无论触发
b=160或b=0的状态切换条件,当前分支末尾的原方向递归调用都会执行,导致同一层级产生两个递归分支,无限扩张。 - 语法错误:第二个分支中
(desplazamiento (+ a 40) ( b 40) c)是非法写法,(b 40)试图将b作为函数调用,实际应该是(- b 40)实现向上移动。 - 无终止条件:函数没有判断何时停止递归,无论
a、b值如何都会持续调用自身。
修复后的代码
(define (desplazamiento a b c) ;; 假设窗口宽度为400,超过则停止递归(可根据实际窗口调整) (if (> a 400) 'done (cond ((equal? c #t) (begin ((draw-solid-rectangle ventana) (make-posn a b) 40 40 "blue") (sleep 0.5) ((clear-solid-rectangle ventana) (make-posn a b) 40 40) ;; 满足条件时切换状态并改变移动方向,否则保持原方向 (if (= b 160) (desplazamiento (+ a 40) (- b 40) #f) (desplazamiento (+ a 40) (+ b 40) #t)))) ((equal? c #f) (begin ((draw-solid-rectangle ventana) (make-posn a b) 40 40 "blue") (sleep 0.5) ((clear-solid-rectangle ventana) (make-posn a b) 40 40) ;; 满足条件时切换状态并改变移动方向,否则保持原方向 (if (= b 0) (desplazamiento (+ a 40) (+ b 40) #t) (desplazamiento (+ a 40) (- b 40) #f))))))) (desplazamiento 0 0 #t)
修复说明
- 添加终止条件:通过顶层
if判断a是否超过窗口宽度,达到后返回'done终止递归。 - 合并递归逻辑:用
if替代嵌套cond,满足状态切换条件时仅执行方向改变的递归,避免同一层级产生多个递归分支。 - 修复语法错误:将
(b 40)改为(- b 40),正确实现向上移动的逻辑。 - 单一递归出口:每个分支仅保留一次递归调用,避免无限循环的分支扩张。
内容的提问来源于stack exchange,提问作者Juan Agudelo
相关产品推荐
相关产品推荐

