方案:从一组三个数字中返回两个最大的数字

时间:2014-09-16 02:01:04

标签: scheme sicp

我应该写一个函数,从一组给定的三个数字中打印出两个更大数字的平方和。

我处理的情况相当笨拙。我没有编写一个返回3个集合中两个最大数字的函数,而是编写了函数,使表达式减少到所需的两个数字。 #SSL功能。

我必须这样做的原因是我无法编写可以将多个值一起返回的LISP函数,并且我无法编写可以读取两个值作为参数的LISP函数。

有没有办法可以抽出其他程序中最大数字的计算?

(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)))
)

4 个答案:

答案 0 :(得分:6)

像往常一样,将问题分解为更容易解决的子问题是一个好主意;我将解释如何编写解决方案,同时我会回答您的问题。首先,让我们找出三个中最大的两个数字并将它们返回到列表中 - 这是一种简单,可移植的方式来返回多个值:

(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用于将sum-square(一个接收两个参数的函数)应用于{返回的结果{1}}(包含两个元素的列表) - 这是我们处理max-two返回的多个值的方式:

max-two

结果如预期:

(define (sum-max a b c)
  (apply sum-square (max-two a b c)))

答案 1 :(得分:4)

这是来自SICP♥(计算机程序的结构和解释)一书的练习1.3。

书中的这一点尚未介绍,也没有必要使用它们。这是我的解决方案(我现在正在从SICP的书中学习)。

首先要提出三个数字中最大的数字:

(define (getlargest a b c) 
  (if (> (if (> a b) a b) c) (if (> a b) a b) c)
  )

getlargest读取:

  • 如果a大于b,则a,否则为b
  • 获取上一步的结果,并以相同的方式将其与c进行比较。
  • 返回 如果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读到:

  • 使用getlargest确定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中来“blackbox”整个事情:

(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))
  )

答案 2 :(得分:3)

首先,此评论并没有解决OP的问题,而是解释了我的观察,并针对给定问题提供了不同的方法。


这是我能想到的两种方法,

  1. 直接方法:尝试查找和评估最初在问题中提出的两个大数字
  2. 间接方法:尝试查找并忽略唯一的最小数字,然后评估其余两个数字。

我更喜欢第二种方法,因为它涉及找到一个数字,而另一种要求更多—我可以想象一种情况,在这种情况下,我们被要求评估列表中的7个最大数字的平方和。例如8。


首先,我将为最终评估定义必要的程序

(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)))

然后,在STklargest2-sum-of-squares过程中运行一些测试

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

答案 3 :(得分:0)

定义一个过程,该过程将三个数字作为参数并返回两个较大数字的平方和。尚未使用的清单。刚刚使用了定义和条件表达式。

(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)))) )

然后测试程序

(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)