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

Scheme 方案:从一组三个数字中返回两个最大的数字,scheme,sicp,Scheme,Sicp,我应该写一个函数,从给定的三个数中打印出两个较大数的平方和 我处理这种情况相当笨拙。我没有编写一个返回3个数中两个最大数的函数,而是编写了一个函数,使表达式减少到两个必需的数SSL函数 我必须这样做的原因是我不能编写一个可以同时返回多个值的LISP函数,也不能编写一个可以读取两个值作为参数的LISP函数 有什么方法可以在其他过程中提取出最大数的计算结果吗? (define (min a b) (if (> a b) b a) ) (define (max a b)

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

我处理这种情况相当笨拙。我没有编写一个返回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)))
)
(定义
(最低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的问题,相反,它解释了我的观察结果,并为给定的问题提供了不同的方法


以下是我能想到的两种方法

  • 直接法:试图找出并评估问题中最初提出的两个较大的数字
  • 间接法:试图找到并忽略唯一最小的数字,然后计算剩余的两个数字
  • 我更喜欢第二种方法,因为它涉及到找到一个单一的数字,而另一个要求更多一点——例如,我可以想象一个场景,在这个场景中,我们被要求计算8个数字列表中7个最大数字的平方和


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

    (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