SICP练习1.3 Racket执行异常:无输出及else语法错误
解决SICP练习1.3的Racket代码问题
首先,我们来看你遇到的两个问题:函数无输出和添加else时的语法报错,根源都是sum-of-biggest-squares函数的cond结构写错了。
你的原始代码问题分析
先看你最初的函数实现:
(define (sum-of-biggest-squares a b c ) (cond ((>= a b) (sum-of-squares a (max b c) ) (sum-of-squares b (max a c) ) ) ) )
- 无输出的原因:当
(>= a b)不成立时,cond没有任何匹配的子句,函数没有返回值,所以解释器不会输出结果。 - 子句内的冗余代码:即使
(>= a b)成立,你在同一个子句里写了两个sum-of-squares表达式——Racket会执行第一个表达式,但只返回最后一个表达式的值,这完全不符合你想取最大两个数平方和的逻辑。
添加else时的语法错误原因
你尝试添加else语句时,应该把它作为cond的第二个子句,但你可能错误地将其放在了cond的括号外部,导致解释器把else当成了普通表达式(而else是cond的特殊关键字,只能作为子句的条件使用),所以才会报错:
exercise_1-3.rkt:23:10: else: not allowed as an expression in: (else (sum-of-squares b (max a c)))
正确的实现方式
你的核心思路是对的:如果a >= b,那么最大的两个数是a和b、c中的较大值;否则最大的两个数是b和a、c中的较大值。只需要修正cond的结构,让每个分支只返回正确的表达式,并补上else分支:
#lang racket (require sicp) (define (square a) (* a a)) (define (sum-of-squares a b) (+ (square a) (square b))) (define (max a b) (cond ((>= a b) a) (else b))) (define (sum-of-biggest-squares a b c) (cond ((>= a b) (sum-of-squares a (max b c))) (else (sum-of-squares b (max a c))))) ; else作为cond的第二个子句,正确匹配所有a < b的情况 ; 测试运行 (sum-of-biggest-squares 5 7 10) ; 会输出149(7² + 10² = 49 + 100 = 149)
更简洁的实现思路
其实还有更简洁的写法,不需要嵌套cond:直接找出三个数中最大的两个数,再计算平方和。比如:
(define (sum-of-biggest-squares a b c) (sum-of-squares (max a b) (max (min a b) c)))
这个逻辑是:先取a和b的最大值,再取a和b的最小值与c的最大值,这两个值就是三个数中最大的两个,直接计算它们的平方和即可。
内容的提问来源于stack exchange,提问作者Tanveer Salim
相关产品推荐
相关产品推荐

