Scheme 方案:从一组三个数字中返回两个最大的数字
我应该写一个函数,从给定的三个数中打印出两个较大数的平方和 我处理这种情况相当笨拙。我没有编写一个返回3个数中两个最大数的函数,而是编写了一个函数,使表达式减少到两个必需的数SSL函数 我必须这样做的原因是我不能编写一个可以同时返回多个值的LISP函数,也不能编写一个可以读取两个值作为参数的LISP函数 有什么方法可以在其他过程中提取出最大数的计算结果吗?Scheme 方案:从一组三个数字中返回两个最大的数字,scheme,sicp,Scheme,Sicp,我应该写一个函数,从给定的三个数中打印出两个较大数的平方和 我处理这种情况相当笨拙。我没有编写一个返回3个数中两个最大数的函数,而是编写了一个函数,使表达式减少到两个必需的数SSL函数 我必须这样做的原因是我不能编写一个可以同时返回多个值的LISP函数,也不能编写一个可以读取两个值作为参数的LISP函数 有什么方法可以在其他过程中提取出最大数的计算结果吗? (define (min a b) (if (> a b) b a) ) (define (max a b)
(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)))
)
(定义
(最低a b)
(如果(>a b)b a)
)
(定义
(最高a b)
(如果(
像往常一样,将问题分解成更容易解决的子问题是个好主意;我将解释如何编写解决方案,同时回答您的问题。首先,让我们从三个数字中找出两个最大的数字,并在列表中返回它们-这是一种简单、可移植的返回多个值的方法:
(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))))
现在,让我们编写一个程序,将两个数字作为输入,进行平方运算,然后将结果相加-这就是我们如何声明接收多个值作为参数的函数:
(define (sum-square x y)
(+ (* x x) (* y y)))
最后,让我们编写程序以获得答案-我们将使用apply
将平方和
(一个接收两个参数的函数)应用于max two
(一个包含两个元素的列表)返回的结果-这就是我们如何处理max two
返回的多个值的方法:
(define (sum-max a b c)
(apply sum-square (max-two a b c)))
结果如预期:
(sum-max 3 1 2)
=> 13
这是来自♥ (计算机程序的结构和解释)书 在这一点上,书中的列表还没有被介绍,也没有必要使用它们。这是我的解决方案(目前我正在学习SICP手册) 第一件事是找出三个数字中最大的一个:
(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恰好是 比a和b都大
(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的内容如下:
- 使用GetMaximum确定a、b或c是最大的数字
- 如果a是最大的数字,将b与c进行比较,并返回b和c中的最大值;同样地
- 如果b是最大的,将a与c进行比较,并返回a和c中最大的一个
- 如果c最大,将a与b进行比较,并返回a和b中最大的一个
(define (sqrsum x y)
(+ (* x x) (* y y))
)
最后,主要功能:
(define (main a b c)
(sqrsum (getlargest a b c) (getmiddle a b c))
)
我们可以通过将所有东西都放在main中来“黑盒”整个事情:
(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))
)
定义一个以三个数字作为参数并返回两个较大数字的平方和的过程。尚未使用列表。刚刚使用了定义和条件表达式
(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)))) )
首先,这个评论并没有解决OP的问题,相反,它解释了我的观察结果,并为给定的问题提供了不同的方法
以下是我能想到的两种方法
首先,我将为最终评估定义必要的程序
(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)))
你可能会喜欢这样:。或者,我们能不能只做
(定义最小的abc)(if(<(if(
,然后对不是最小的两个整数做平方和
?我认为它稍微短一点,因为我们不必同时找到最大值和中间值:)这是一个很好的方法,但您肯定应该“选择(其他(平方和x y)))
”。没有理由在两次以上的比较中浪费周期,而使用else
更清楚地传达了这一含义:对于cond
的这个分支,只有一种可能性可用。但好的方法是+1。
(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> (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