如何用递归实现检查列表中所有奇数都大于10的eval函数
问题分析与解决
原代码错误原因
你的代码逻辑完全不符合需求,当前守卫规则是只要碰到一个大于10的奇数就直接返回True,但需求是「所有奇数都大于10」,等价于只要存在任意一个奇数小于等于10,就返回False,属于逻辑写反导致的问题,和列表顺序无关。
先排序的思路是否可行?
可行但没有必要:
- 升序排序后所有奇数里最小的会排在最前面,只要碰到第一个小于等于10的奇数就可以直接返回False,后续元素不需要检查,逻辑上是通顺的
- 但排序需要额外的O(nlogn)时间复杂度,直接遍历列表一次的时间复杂度只有O(n),后者效率更高
实现方案
方案1:无需排序的正确递归实现(推荐)
eval :: [Int] -> Bool eval [] = True eval (x:xs) -- 遇到小于等于10的奇数直接返回False,不满足需求 | odd x && x <= 10 = False -- 其他情况(偶数/大于10的奇数)继续检查剩余列表 | otherwise = eval xs
该代码可直接通过所有测试用例:
eval [] == True → 符合 eval [1] == False → 符合 eval [2] == True → 符合 eval [1, 11, 21] == False → 符合 eval [2, 12, 22] == True → 符合 eval [21, 11] == True → 符合
方案2:先排序再递归的实现
如果一定要用排序的思路实现,代码如下,需要导入Data.List的sort方法:
import Data.List (sort) eval :: [Int] -> Bool -- 先对输入列表升序排序,再调用递归辅助函数检查 eval lst = evalSorted (sort lst) where evalSorted [] = True evalSorted (x:xs) | odd x && x <= 10 = False | otherwise = evalSorted xs
内容的提问来源于stack exchange,提问作者idontknowhowtocode
相关产品推荐
相关产品推荐

