You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统计数字列表中的奇偶个数?Haskell函数实现求助

解决Haskell列表奇偶次数统计问题

嘿,我来帮你搞定这个统计数字列表奇偶次数的需求~先看看你现有代码里的小问题,再给你几种靠谱的实现方案:

现有代码的几个小问题

  1. 奇偶判断逻辑有误:你用div来判断偶数是不可靠的,比如负数-2,-2 div 2会得到-1,不等于0,这就会把它错误判定成奇数。正确的做法应该用mod运算符,x mod 2 == 0才是判断偶数的准确方式。
  2. 代码冗余:分开写counteven和countodd需要两次遍历列表,其实可以优化成一次遍历搞定,效率更高。
  3. 未完成核心函数:你的oddsAndEvens只写了一半函数头,还需要补全实现才能返回预期的元组结果。

修正&优化后的实现

方案1:基于你现有代码补全

先修正counteven和countodd的判断逻辑,再完成oddsAndEvens:

counteven :: [Integer] -> Integer
counteven [] = 0
counteven (x:xs) | x `mod` 2 == 0 = 1 + counteven xs
                 | otherwise = counteven xs

countodd :: [Integer] -> Integer
countodd [] = 0
countodd (x:xs) | x `mod` 2 /= 0 = 1 + countodd xs
                | otherwise = countodd xs

oddsAndEvens :: [Integer] -> (Integer, Integer)
oddsAndEvens xs = (counteven xs, countodd xs)

测试一下你给的例子:

-- 输入[1,2,3,4,5],会返回(2,3),完全符合你的预期
oddsAndEvens [1,2,3,4,5]

方案2:一次遍历的高效实现

上面的方案需要两次遍历列表,对于大型数据来说有点浪费。我们可以用递归或者折叠函数,一次遍历就统计出两个计数:

递归版本

oddsAndEvens :: [Integer] -> (Integer, Integer)
-- 空列表的情况,奇偶计数都是0
oddsAndEvens [] = (0, 0)
-- 处理每个元素,递归更新计数
oddsAndEvens (x:xs)
    | x `mod` 2 == 0 = let (evens, odds) = oddsAndEvens xs in (evens + 1, odds)
    | otherwise = let (evens, odds) = oddsAndEvens xs in (evens, odds + 1)

折叠(foldl)版本(更简洁)

oddsAndEvens :: [Integer] -> (Integer, Integer)
oddsAndEvens = foldl count (0, 0)
    where count (evens, odds) x
            | x `mod` 2 == 0 = (evens + 1, odds)
            | otherwise = (evens, odds + 1)

这个折叠版本代码更紧凑,而且只遍历一次列表,性能是最优的。

小提示

一定要用mod而不是div来判断奇偶,因为mod能正确处理负数的情况——比如(-4) mod 2结果是0,会被正确判定为偶数;而(-4) div 2是-2,不等于0,会直接出错哦。

内容的提问来源于stack exchange,提问作者Amy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:37:16