我正在关注计算机程序的结构和解释,在尝试解决Ex 1.3时,我作为我的第一次尝试得到了以下代码:
(define (sumsq a b c)( (define highest (if (> (if (> a b) a b) (if (> a c) a c)) (if (> a b) a b) (if (> a c) a c))) (define second_h (if (> (if (> a b) b a) (if (> a c) c a)) (if (> a b) b a) (if (> a c) c a))) (+ (* highest highest) (* second_h second_h)))
它没有用,我查找了解决方案并在SICP Wiki上找到了它们
;; ex 1.3 ;; implemented using only techniques covered to this point (define (square x) (* x x)) (define (sum-of-squares x y) (+ (square x) (square y))) (define (largest-two-of-three x y z) (if (>= x y) (sum-of-squares x (if (>= y z) y z)) (sum-of-squares y (if (>= x z) x z))))
不同之处在于我使用多个语句来定义变量然后对方块求和,而正确的方法是将每个行定义为函数.
Scheme中的函数是否为一个衬里?还是我错过了整件事?
您应该使用适当的缩进和换行符来概述您的程序流程.您的第一个提案如下所示:
(define (sumsq a b c) ((define highest (if (> (if (> a b) a b) (if (> a c) a c)) (if (> a b) a b) (if (> a c) a c))) (define second-h (if (> (if (> a b) b a) (if (> a c) c a)) (if (> a b) b a) (if (> a c) c a))) (+ (* highest highest) (* second-h second-h)))
首先要注意的是:括号不匹配; 还有一个比关闭更开放.仔细检查显示第二行中的一个左括号是错误的.顺便说一句,这是在你的第一行结束时以某种方式悬挂的那个.我猜想当你试图评估这个时,没有任何事情发生,因为读者等待声明的结束.
适当的缩进非常重要.我认为SICP没有明确解释它,尽管这些例子通常是这样做的.我在这里找到了一个风格指南.
第二个观察:你重复了很多.在所有那些嵌套if
语句中,我不确定你是否真的得到了正确的值.看看你发现的解决方案,看看如何大大简化这一点.
您尝试通过提供子结果名称来分解复杂性.打破复杂性是好的,但通常更好的是不是结果,而是概念.想想你做了什么,然后命名这些活动.这些是功能,它们构成了你最终几乎无助于解决问题的语言.
你写的(减去一个额外的paren)是:
(define (sumsq a b c) (define highest (if (> (if (> a b) a b) (if (> a c) a c)) (if (> a b) a b) (if (> a c) a c))) (define second_h (if (> (if (> a b) b a) (if (> a c) c a)) (if (> a b) b a) (if (> a c) c a))) (+ (* highest highest) (* second_h second_h)))
他们的解决方案确实将正方形和平方和分成单独的函数,但我不认为那是重要的.不写(+ (* a a) (* b b))
不会阻止你为你正在计算的两个值命名,这会让你在最后把这个函数写成一个大表达式,但现在还有更大的事情要担心.
我认为你遇到的问题是你的(如果......)表达式太大而不易理解.请注意,有两种模式出现多次:(if (> a b) a b)
和(if (> a b) b a)
.这些是max和min函数,因此定义它们非常有用:
(define (min a b) (if (< a b) a b)) (define (max a b) (if (< a b) b a))
这样,您可以将解决方案重写为:
(define (sumsq a b c) (define highest (if (> (max a b) (max a c)) (max a b) (max a c))) (define second_h (if (> (min a b) (min a c)) (min a b) (min a c))) (+ (* highest highest) (* second_h second_h)))
再次简化它给出:
(define (sumsq a b c) (define highest (max (max a b) (max a c))) (define second_h (max (min a b) (min a c))) (+ (* highest highest) (* second_h second_h)))
注意这个写作更容易理解,(max (max a b) (max a c))
显然是最大的a
b
和c
,并且实际上可以重写为(max (max a b) c)
.second_h
但是,看一下,这是不正确的.a
三个值中最小的一个会发生什么?
他们在解决方案中使用的技巧是先比较x
和y
.if x < y
,那么你知道这y
不是三者中最小的,所以它要么是最高要么是第二高.你将要使用其他的数字是较高x
和z
,因为这两个下部将是三者中最小的,要忽略.类似的逻辑适用于y < x
.