题
我下面的计算机程序的结构和解读的同时试图解决防爆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维基一>
;; 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))))
不同的是,我使用多个语句来定义变量,然后求和的平方,而正确的方法是定义每个我的行作为功能。
是在方案一衬垫功能?还是我错过了整个事情?
解决方案
你写什么(减去一个额外的括号)是:
(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)
。这些是最大和最小功能,从而来定义它们是非常有用的,例如:
(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
。如果x < y
,那么你知道,y
不是三者中最小的,所以它要么是最高或次高。你会想使用其他号码是x
和z
的更高,因为这两个下部将是三者中最小的,要忽略。类似的逻辑适用于当y < x
。
其他提示
您要使用适当的缩进和换行符克服你的程序流程的概述。然后,您的第一个提案内容是这样的:
(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
声明,我真的不知道你是否真的得到了正确的价值观了。看看你发现怎么看这个可以大大简化了解决方案。
您试图通过给子结果的名字,打破了复杂性。分手的复杂性是好的,但它通常是最好的名字不是结果,而是概念。想想你做什么,然后命名这些活动。这些都是函数,它们构成了你最后几乎平凡解决你的问题的语言。
一个方案的想法是创建为每个概念操作的功能bottom-up programming
。这是一个在许多函数式编程语言推荐的方法。
通过这种方法你结束了很多实施上一个参数逻辑操作小的功能。这样,你的代码最终被更加模块化和清洁。
您溶液具有以下形式:(定义(FUNC PARAM)(定义...)(定义...))
但是限定需要这种形式:(定义(FUNC PARAM)体)
身体是函数的实现......它做什么,它返回什么。你的身体只是更多的定义,从来没有做任何事情。所以这就是为什么你的解决方案没有被Scheme解释接受。
要回答“是方案函数的单行?”您需要调查 “开始” 的形式,这看起来像这样:(开始(+ 11)(+ 2 2))=> 4
在上面的例子中,(+ 1 1)的结果只是抛出方式,所以可以看到,开始只有真正有意义当它内部的东西有副作用。
您应该知道,计划的某些部分(主要是让和lambda)有绕在自己身上隐含的开始。因此,这是有效的:
(let ((x 1))
(+ 1 1)
(+ 2 2))
即使没有开始。这使得简单的代码编写。
最后,当你继续学习计划,总是试图找到一种方法,做一些没有开始,没有任何副作用。特别是在大多数方案书的前几章,如果你的想法,“我要设置变量,那么,我想这样做,那么这......”你可能被困在你的程序中旧的方式,而不是做它的计划方式。这没有什么错的副作用在所有的,但大量使用他们的意思你是不是真的规划方案效果最好的方式。
1.3锻炼要求你定义一个带有三个号作为参数并返回两个较大数的平方和的过程。这很容易定义那样使用内置的计划程序square
,max
和min
一个过程,但我们还没有在书中点遇到这些程序呢,所以我定义它们为好。
(define (square x)
(* x x))
(define (max x y)
(if (> x y) x y))
(define (min x y)
(if (< x y) x y))
(define (sum-of-highest-squares x y z)
(+ (square (max x y))
(square (max (min x y) z))))
在sum-of-highest-squares
过程的工作原理是将最大的x和y的平方和最大剩余的两个(最小x的平方和(这两个的最大从为最低三个的消除) Y,这将是取其值由第一步遗留),和z。
请注意:这是我的博客文章 SICP练习1.1 - 1.5 。有迹象表明,将带你到了很多其他SICP解决方案的出现,以及链接。