Scheme: Returning two largest numbers from a set of three numbers
我应该写一个函数,从给定的三个数字中打印出两个更大数字的平方和。
我相当笨拙地处理了这种情况。我没有编写返回一个3中最大的两个数字的函数,而是编写了该函数,以便将表达式简化为两个所需的数字。 #SSL功能。
之所以必须这样做,是因为我无法编写可以一起返回多个值的LISP函数,也无法编写可以读取两个值作为参数的LISP函数。
是否可以通过其他方法抽象出最大数的计算?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | (define (min a b) (if (> a b) b a) ) (define (max a b) (if (< a b) b a) ) (define (square a) ( * a a) ) (define (ssl a b c) (+ (square (max a b)) (square (max (min a b) c))) ) |
这是SICP a?¥(计算机程序的结构和解释)书中的练习1.3。
目前,书中的清单尚未介绍,因此无需使用它们。这是我的解决方案(目前我正在学习SICP书籍)。
第一件事是拿出三个数字中最大的一个:
1 2 3 | (define (getlargest a b c) (if (> (if (> a b) a b) c) (if (> a b) a b) c) ) |
最大读取:
- 如果a大于b,则为a,否则为b
- 取上一步的结果,并以相同的方式将其与c进行比较。
-
要么返回
a和b之间的最大数字,如果c恰好是c,则返回c
比a和b都大。
第二件事是拿出中间数字:
1 2 3 4 5 6 | (define (getmiddle a b c) (cond ((= (getlargest a b c) a) (if (> b c) b c)) ((= (getlargest a b c) b) (if (> a c) a c)) ((= (getlargest a b c) c) (if (> a b) a b)) ) ) |
getmiddle读取:
- 使用getlargest确定a或b或c是最大的数字。
- 如果a是最大数,则将b与c进行比较,并返回b和c中的最大值;相似地,
- 如果b是最大的,则将a与c进行比较,然后返回a和c的最大值
- 如果c是最大的,则将a与b进行比较,并返回a和b中的最大值
现在我们需要一个函数来计算两个数字的平方和:
1 2 3 | (define (sqrsum x y) (+ (* x x) (* y y)) ) |
最后,主要功能:
1 2 3 | (define (main a b c) (sqrsum (getlargest a b c) (getmiddle a b c)) ) |
通过将所有内容放入main中,我们可以将整个事情"黑匣子":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | (define (main a b c) (define (getlargest) (if (> (if (> a b) a b) c) (if (> a b) a b) c) ) (define (getmiddle) (cond ((= (getlargest) a) (if (> b c) b c)) ((= (getlargest) b) (if (> a c) a c)) ((= (getlargest) c) (if (> a b) a b)) ) ) (define (sqrsum x y) (+ (* x x) (* y y)) ) (sqrsum (getlargest) (getmiddle)) ) |
与往常一样,将问题分解为易于解决的子问题是一个好主意;我将解释如何编写解决方案,同时我将回答您的问题。首先,让我们找出三个数字中的两个最大数字,然后将它们返回到列表中-这是一种简单,可移植的方法,可以返回多个值:
1 2 3 4 5 6 7 8 | (define (max-two a b c) (if (>= a b) (if (>= b c) (list a b) (list a c)) (if (>= a c) (list b a) (list b c)))) |
现在让我们编写一个过程,该过程将两个数字作为输入,将它们平方后再加上结果-这就是我们如何声明一个将多个值作为参数接收的函数的方法:
1 2 | (define (sum-square x y) (+ (* x x) (* y y))) |
最后,让我们组成获取答案的过程-我们将使用
返回的多个值的方法
1 2 | (define (sum-max a b c) (apply sum-square (max-two a b c))) |
结果符合预期:
1 2 | (sum-max 3 1 2) => 13 |
首先,此注释未解决OP \\的问题,而是解释了我的观察,并针对给定的问题提供了不同的方法。
这是我能想到的两种方法,
我更喜欢第二种方法,因为它涉及找到一个数字,而另一个则要多一些?我可以想象一个场景,例如,要求我们评估8个列表中的7个最大数字的平方和。
首先,我将为最终评估定义必要的程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | (define (square x) (* x x)) (define (sum-of-squares x y) (+ (square x) (square y))) (define (largest2-sum-of-squares x y z) ;;; x is excluded (cond ((and (<= x y) (<= x z)) (sum-of-squares y z)) ;;; y is excluded ((and (<= y x) (<= y z)) (sum-of-squares x z)) ;;; z is excluded ((and (<= z x) (<= z y)) (sum-of-squares x y))) ;;; Note: It's also tempting to go for (else (sum-of-squares x y))) |
然后,在STk
上的
1 2 3 4 5 6 | STk> (largest2-sum-of-squares 1 2 3) 13 STk> (largest2-sum-of-squares 1 1 3) 10 STk> (largest2-sum-of-squares -3 4 0) 16 |
定义一个过程,该过程以三个数字作为参数,并返回两个较大数字的平方和。尚未使用的清单。刚刚使用的定义和条件表达式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | (define (square x) (* x x)) (define (sum-of-square x y) (+ (square x) (square y))) (define (largest a b c) (cond ((and (> a b) (> a c)) a) ((and (> b a) (> b c)) b) ((and (> c b) (> c a)) c))) (define (larger a b) (if (< a b) b a)) (define (sum-of-two-larger-square a b c) (cond ((= (largest a b c) a) (sum-of-square a (larger b c))) ((= (largest a b c) b) (sum-of-square b (larger a c))) ((= (largest a b c) c) (sum-of-square c (larger a b)))) ) |
然后测试程序
1 2 3 4 5 6 7 8 | (largest 1 2 3) (larger 1 2) (square 3) (sum-of-square 2 3) (two-larger-of-three 1 2 3) (sum-of-two-larger-square 1 2 3) (sum-of-two-larger-square 12 45 100) (sum-of-square 45 100) |