Haskell中nSubstrings函数实现求助:字符串拆分问题
解决方案
你可以通过排序分组+提取字符的思路完成需求,以下是完整实现:
import Data.List (sortOn, groupBy) import Data.Function (on) nSubstrings :: String -> Int -> [String] nSubstrings xs 0 = [] nSubstrings xs n | n <= 0 = [] | otherwise = map (map fst) grouped where -- 为每个字符绑定循环的组号(1到n) pairedChars = zip xs (cycle [1..n]) -- 按组号排序,让同组字符相邻 sortedPairs = sortOn snd pairedChars -- 按组号分组 grouped = groupBy ((==) `on` snd) sortedPairs
代码解释
对应你提到的思路,我们拆解成三步:
- 绑定组号:用
zip xs (cycle [1..n])把每个字符和循环的1~n组号配对,得到类似[('H',1), ('A',2), ..., ('N',2)]的列表,这和你写的splitOnPairs逻辑一致。 - 按组号排序:用
sortOn snd把所有配对按组号从小到大排序,这样同一组号的字符会集中在一起,就得到了你期望的排序后的列表。 - 分组并提取字符:用
groupBy ((==)onsnd)按组号分组,再通过map (map fst)把每个分组里的字符提取出来,拼接成最终的子串。
测试验证
运行示例输入:
nSubstrings "HASKELLISFUN" 0 -- 输出 [] nSubstrings "HASKELLISFUN" 1 -- 输出 ["HASKELLISFUN"] nSubstrings "HASKELLISFUN" 5 -- 输出 ["HLU","ALN","SI","KS","EF"]
完全符合题目要求的结果。
优化说明
- 如果不想导入
Data.Function,可以把groupBy的条件写成groupBy (\a b -> snd a == snd b),效果完全一致。 n=1的情况不需要单独处理(代码会自动把所有字符分到同一组),但单独写nSubstrings xs 1 = [xs]可以提升小n场景的效率。
内容的提问来源于stack exchange,提问作者FunName
相关产品推荐
相关产品推荐

