Haskell中如何借助统计频次的card函数求解列表的众数
Haskell 基于频次统计Map求列表众数的实现
你已经实现的频次统计函数如下:
card :: [Int] -> Map Int Int card = Map.fromListWith (+) . (`zip`[1,1..])
你需要先导入以下依赖模块保证代码可运行:
import qualified Data.Map as Map import Data.Ord (comparing) import Data.List (maximumBy)
实现方案
方案1:取单个众数(仅返回频次最高的第一个元素)
该实现适合默认众数唯一的场景,直接按频次排序取最大值即可:
mode :: [Int] -> Int mode = fst . maximumBy (comparing snd) . Map.toList . card
测试你的示例输入[1,2,5,1,1,2],调用mode [1,2,5,1,1,2]会返回结果1,符合预期。
方案2:取全部众数(返回所有频次最高的元素)
如果存在多个元素频次相同且均为最高值的场景,需要过滤出所有符合条件的元素:
modes :: [Int] -> [Int] modes xs = map fst $ filter (\(_, cnt) -> cnt == maxCnt) pairList where pairList = Map.toList $ card xs maxCnt = maximum $ map snd pairList
比如输入列表[1,1,2,2,3],调用modes [1,1,2,2,3]会返回[1,2]。
方案3:带空输入安全处理的版本
上面两个方案在输入空列表时会抛出异常,你可以用Maybe类型处理边界情况:
safeMode :: [Int] -> Maybe Int safeMode [] = Nothing safeMode xs = Just $ fst . maximumBy (comparing snd) . Map.toList $ card xs safeModes :: [Int] -> [Int] safeModes [] = [] safeModes xs = map fst $ filter (\(_, cnt) -> cnt == maxCnt) pairList where pairList = Map.toList $ card xs maxCnt = maximum $ map snd pairList
内容的提问来源于stack exchange,提问作者programmer2000
相关产品推荐
相关产品推荐

