Haskell字符串转指定格式列表:支持多组字符数字对
解决Haskell的enlarge函数多组输入问题
我来帮你搞定这个问题!你的原函数只能处理单组字符数字对,要支持多组输入,核心思路确实是递归处理剩余字符串,但之前的尝试在结构和递归逻辑上有点问题,我来一步步拆解:
原函数的局限
原函数:
enlarge :: String -> [(Char,Int)] enlarge [] = [] enlarge xs = [(a,b) | (b,a:_) <- reads xs]
reads 处理类似 "5a3b" 的输入时,只会返回 [(5, "a3b")]——也就是只解析开头的数字,剩下的 "a3b" 并没有被继续处理,所以只能得到第一组结果。
正确的递归实现
我们需要每次解析一组(数字+后续第一个字符),然后递归处理剩下的字符串。这里用case表达式处理reads的返回结果会更清晰,还能兼顾非法输入的情况:
enlarge :: String -> [(Char, Int)] enlarge [] = [] -- 空输入返回空列表 enlarge xs = case reads xs of -- 解析到数字,且数字后面有对应字符 [(num, char:rest)] -> (char, num) : enlarge rest -- 解析到数字但后面没有字符(比如输入以数字结尾),忽略这组 [(num, "")] -> [] -- 无法解析数字(比如输入以非数字开头),返回空 [] -> [] -- 其他异常情况,返回空 _ -> []
逻辑说明
- 当输入是空字符串时,直接返回空列表(递归终止条件)。
- 用
reads xs尝试解析开头的数字:- 如果成功解析出数字
num,且剩余字符串char:rest有至少一个字符(char就是对应要配对的字符),就把(char, num)加入结果列表,然后递归处理剩下的rest。 - 如果解析出数字但后面没有字符,直接返回空(避免报错)。
- 如果无法解析数字(比如输入开头是字母),也返回空。
- 如果成功解析出数字
测试示例
- 输入
"5a3b",输出[('a',5),('b',3)] - 输入
"10x2y",输出[('x',10),('y',2)] - 输入
"7z",输出[('z',7)] - 输入
"abc",输出[]
你之前尝试的问题
你写的:
enlarge xs = [((a,b),ts) | ((b,a),ts) <- reads xs, reads ts]
有两个关键问题:
reads xs返回的是[(数字, 剩余字符串)],不是((数字, 字符), 剩余字符串),结构完全不匹配。- 没有递归调用
enlarge处理剩余的ts,只是判断reads ts是否有结果,这无法把后续组的结果加入列表。
内容的提问来源于stack exchange,提问作者Kappa123
相关产品推荐
相关产品推荐

