#f 在 repl.it 内输出方案结果
#f output for scheme result inside repl.it
我正在做一些来自 Structure and Interpretation of Computer Programs
的问题
我的案例在 repl.it 解释器中输出 #f 作为有效结果。我正在申请 (and (not (max a b c)) (not (min a b c))) 以获得中间值。
我已经尝试重新排列中间函数的值。最大和最小函数工作正常。
(define (max a b c)
(cond
((and(>= a b)(>= a c)) a)
((and(>= b a)(>= b c)) b)
((and(>= c a)(>= c b)) c)
))
(define (min a b c)
(cond
((and(<= a b)(<= a c)) a)
((and(<= b a)(<= b c)) b)
((and(<= c a)(<= c b)) c)
))
(define (mid a b c)
(and
(not (max a b c))
(not (min a b c))
))
(mid 10 8 6)
repl.it 方案解释器中的输出是:
=> #f
我预计会出现某种错误或数字值错误,但此代码 return 是绿色的 #f 所以我假设它意味着错误?我如何使用条件表达式将此代码修复为 return a mid?
我意识到我从 max AND min 传递了一个 NOT,这就是为什么它每次都评估为 false 的原因,因为这些表达式总是有一个错误的结果。我继续使用比较来获得正确的解决方案,并调整了例外情况,将中间值设为一个值,如果它不小于最大值或大于最小值,则重复三次或两次。唯一令人不安的是,我必须基本上表达所有有效条件以隔离中间数,并且不能将中间数明确定义为不是最大数也不是最小数。话虽如此,必须有更好的方法来减少这些功能并消除大量比较...
(define (mid a b c)
(cond
((and(< a (max a b c))(> a (min a b c))) a)
((and(< b (max a b c))(> b (min a b c))) b)
((and(< c (max a b c))(> c (min a b c))) c)
(else (cond
((= (min a b c) (max a b c)) a)
((= a b) a)
((= a c) a)
((= b c) b)
))
))
我认为值得考虑需要进行多少次测试才能计算这些东西:要在任何排序运算符下计算三个元素的极值,您只需进行不超过 3 次比较:
(define (extremum/3 ordered? a b c)
;; find the extremum of three elements under ordered?
(cond ((and (ordered? a b) (ordered? a c)) a)
((ordered? b c) b)
(else c)))
有了这个通用函数,您现在可以轻松定义 max/3 和 min/3:
(define (max/3 a b c)
(extremum/3 >= a b c))
(define (min/3 a b c)
(extremum/3 <= a b c))
计算三个元素的中点也只需要三个测试:
(define (mid/3 a b c)
(if (>= a b)
(if (>= a c)
;; a is greatest, so we need to pick b or c
(if (>= b c) b c)
;; a is the mid point
a)
(if (>= a c)
;; a is the mid point
a
;; a is the minimum, pick b or c
(if (>= c b) b c))))
考虑需要进行多少次比较才能找到 n 项的中点,这很有趣。
我正在做一些来自 Structure and Interpretation of Computer Programs
的问题我的案例在 repl.it 解释器中输出 #f 作为有效结果。我正在申请 (and (not (max a b c)) (not (min a b c))) 以获得中间值。
我已经尝试重新排列中间函数的值。最大和最小函数工作正常。
(define (max a b c)
(cond
((and(>= a b)(>= a c)) a)
((and(>= b a)(>= b c)) b)
((and(>= c a)(>= c b)) c)
))
(define (min a b c)
(cond
((and(<= a b)(<= a c)) a)
((and(<= b a)(<= b c)) b)
((and(<= c a)(<= c b)) c)
))
(define (mid a b c)
(and
(not (max a b c))
(not (min a b c))
))
(mid 10 8 6)
repl.it 方案解释器中的输出是:
=> #f
我预计会出现某种错误或数字值错误,但此代码 return 是绿色的 #f 所以我假设它意味着错误?我如何使用条件表达式将此代码修复为 return a mid?
我意识到我从 max AND min 传递了一个 NOT,这就是为什么它每次都评估为 false 的原因,因为这些表达式总是有一个错误的结果。我继续使用比较来获得正确的解决方案,并调整了例外情况,将中间值设为一个值,如果它不小于最大值或大于最小值,则重复三次或两次。唯一令人不安的是,我必须基本上表达所有有效条件以隔离中间数,并且不能将中间数明确定义为不是最大数也不是最小数。话虽如此,必须有更好的方法来减少这些功能并消除大量比较...
(define (mid a b c)
(cond
((and(< a (max a b c))(> a (min a b c))) a)
((and(< b (max a b c))(> b (min a b c))) b)
((and(< c (max a b c))(> c (min a b c))) c)
(else (cond
((= (min a b c) (max a b c)) a)
((= a b) a)
((= a c) a)
((= b c) b)
))
))
我认为值得考虑需要进行多少次测试才能计算这些东西:要在任何排序运算符下计算三个元素的极值,您只需进行不超过 3 次比较:
(define (extremum/3 ordered? a b c)
;; find the extremum of three elements under ordered?
(cond ((and (ordered? a b) (ordered? a c)) a)
((ordered? b c) b)
(else c)))
有了这个通用函数,您现在可以轻松定义 max/3 和 min/3:
(define (max/3 a b c)
(extremum/3 >= a b c))
(define (min/3 a b c)
(extremum/3 <= a b c))
计算三个元素的中点也只需要三个测试:
(define (mid/3 a b c)
(if (>= a b)
(if (>= a c)
;; a is greatest, so we need to pick b or c
(if (>= b c) b c)
;; a is the mid point
a)
(if (>= a c)
;; a is the mid point
a
;; a is the minimum, pick b or c
(if (>= c b) b c))))
考虑需要进行多少次比较才能找到 n 项的中点,这很有趣。