Racket递归抽象报错:list-superlative函数>运算符参数类型错误
错误原因
你代码的核心问题是比较逻辑的参数处理错误:
list-superlative函数的返回值是列表中的原始元素,不是经过值函数vf转换后的比较值- 你在
>比较时,只对左侧的(first nelox)调用了vf做值转换,右侧直接传入了递归返回的原始元素 - 跑字符串测试用例时,右侧传入的是字符串类型的值,
>运算符只能比较实数,因此触发类型错误。
另外你当前写法对剩余列表递归调用了两次list-superlative,会产生大量冗余计算,列表长度较大时效率会指数级下降。
修正方案
比较时必须对两侧参与对比的元素都调用vf做值转换,同时缓存递归结果避免重复计算,修正后的代码如下:
; list-superlative : [NE-List-of X] (X -> Number) -> X ; 返回非空列表中,经值函数计算后结果最大的原始元素 (check-expect (list-superlative (cons "hello" (cons "hi" (cons "hey" '()))) string-length) "hello") (check-expect (list-superlative (cons 1 (cons 2 (cons 3 '()))) identity) 3) (define (list-superlative nelox vf) (cond [(empty? (rest nelox)) (first nelox)] [(cons? (rest nelox)) (local [(define rest-max (list-superlative (rest nelox) vf))] (if (> (vf (first nelox)) (vf rest-max)) (first nelox) rest-max))]))
改动说明
- 核心修复:给
>运算符右侧的递归返回值也加上vf调用,保证参与比较的两个值都是数值类型,解决类型不匹配错误 - 性能优化:通过
local绑定剩余列表的最大值结果,只做一次递归计算,将时间复杂度从指数级优化为线性 - 注释修正:原函数签名注释中值函数的类型标注错误,值函数的作用是将列表元素映射为可比较的数值,正确签名为
(X -> Number)而非(X -> X)
内容的提问来源于stack exchange,提问作者daniel
相关产品推荐
相关产品推荐

