Haskell group函数问题:首元素缺失的代码修复求助
修复你的
group函数首元素缺失问题 嗨,我来帮你排查这个bug!你遇到的首元素缺失问题,根源在于初始调用groupHelper时没有把第一个元素加入结果列表。
问题分析
你的group函数定义是:
group (x:xs) = groupHelper xs x []
这里你直接把第一个元素x作为prev传入,但结果列表fs是空的——也就是说,第一个元素完全没有被添加到最终的结果里,后续处理的都是xs里的元素,自然第一个子列表会少一个元素。
修复方案
只需要修改group函数的第二个子句,把第一个元素作为初始子列表传入groupHelper即可:
group [] = [] group (x:xs) = groupHelper xs x [[x]] -- 这里把[]改成[[x]] groupHelper :: Eq a => [a] -> a -> [[a]] -> [[a]] groupHelper [] prev fs = fs groupHelper (x:xs) prev [] = groupHelper xs prev [[x]] groupHelper (x:xs) prev fs = if (x == prev) then groupHelper xs x ((init fs) ++ [(last fs ++ [x])]) else groupHelper xs x (fs ++ [[x]])
验证修复效果
现在测试你的示例:
- 输入
group [1,1,2,1,3,3,3],输出变为[[1,1],[2],[1],[3,3,3]],符合预期 - 输入
group "aaabbcdddd",输出变为["aaa","bb","c","dddd"],完全正确
额外优化小建议
你的groupHelper里用init fs和last fs的方式效率不高(因为init和last对于长列表是O(n)操作),如果想优化的话,可以调整helper函数的参数,让它跟踪当前正在构建的子列表,而不是每次去修改结果列表的最后一个元素。比如:
group :: Eq a => [a] -> [[a]] group [] = [] group (x:xs) = groupHelper xs [x] [] where groupHelper :: Eq a => [a] -> [a] -> [[a]] -> [[a]] groupHelper [] current groups = groups ++ [current] groupHelper (y:ys) current groups | y == head current = groupHelper ys (current ++ [y]) groups | otherwise = groupHelper ys [y] (groups ++ [current])
这个版本的helper函数维护当前正在收集的相同元素子列表current,避免了频繁的init和last操作,效率更高哦。
内容的提问来源于stack exchange,提问作者Jan Kreischer
相关产品推荐
相关产品推荐

