Scheme实现mean函数计算平均值结果错误该如何修正
问题分析
你当前代码存在三个核心问题:
- 语法错误:代码首行多了一层冗余的左括号,符合规范的Scheme实现运行这段代码会直接报语法错误,你能得到运行结果说明实际执行时已经去掉了这层括号。
- 逻辑认知偏差:
- 现有逻辑对算术平均值的计算是正确的:
(list 1 2 3 4)的元素总和为10,列表长度为4,10/4=2.5,Scheme返回的2 1/2是精确分数的带分数表示形式,和2.5完全等价,是符合数学定义的正确结果。 - 你预期得到结果2、对应10/5=2的计算逻辑,要么是误将4个元素的列表长度计数为5,要么是需要做整数整除取整(舍去小数部分),而非返回精确的平均值。
- 现有逻辑对算术平均值的计算是正确的:
- 编码隐患:你使用
list作为函数参数名,会覆盖Scheme内置的list构造过程,属于不良编码实践,容易引发后续代码异常。
修改方案
根据你的实际需求二选一即可:
方案1:返回标准算术平均值
如果需要计算数学定义上的平均值,仅需修正语法问题、替换参数名避免内置过程覆盖即可;如果需要返回浮点数而非分数形式,可以在除法运算时做类型转换:
; 求和函数,参数名替换为lst避免覆盖内置list过程 (define (sum lst) (if (null? lst) 0 (+ (car lst) (sum (cdr lst))))) (define (mean lst) (if (null? lst) 0 ; 乘以1.0将长度转为浮点型,触发浮点除法返回小数结果 (/ (sum lst) (* 1.0 (length lst))))) ; 计算1-4的平均值,返回2.5 (mean (list 1 2 3 4)) ; 如果要得到10/5=2的结果,传入5个元素总和为10的列表即可,例如(0 1 2 3 4) (mean (list 0 1 2 3 4))
方案2:返回整数整除结果
如果你需要舍去小数部分、返回整数形式的结果,将除法过程替换为Scheme内置的整数整除过程quotient即可:
(define (sum lst) (if (null? lst) 0 (+ (car lst) (sum (cdr lst))))) (define (mean lst) (if (null? lst) 0 ; quotient执行整数除法,直接舍去小数部分 (quotient (sum lst) (length lst)))) ; 计算1-4的平均值,10整除4返回2,和你的预期结果一致 (mean (list 1 2 3 4))
内容的提问来源于stack exchange,提问作者ani2016
相关产品推荐
相关产品推荐

