如何用递归实现统计字符串开头指定字符出现次数的Haskell函数
解决Haskell递归函数length_char的实现问题
原有代码的问题
- 类型签名顺序错误:你定义的
length_char :: String -> Char -> Int要求先传字符串再传字符,但实际调用是length_char 'a' "aaabaa"(先字符后字符串),类型不匹配是报错的直接原因。 - 逻辑不符合需求:
filter会过滤整个字符串里的所有目标字符,统计的是全局出现次数,而不是开头连续出现的次数,完全不符合你要的功能。
符合要求的递归实现
按照你的限制(仅用head/tail,递归实现,禁用其他库函数),用模式匹配的方式实现最简洁:
length_char :: Char -> String -> Int length_char _ [] = 0 -- 空字符串,没有字符可匹配,返回0 length_char c (x:xs) | x == c = 1 + length_char c xs -- 首字符匹配,加1后递归处理剩余字符串 | otherwise = 0 -- 首字符不匹配,连续匹配结束,返回0
代码工作原理
- 空字符串分支:不管传入什么字符,直接返回0,因为没有字符可以匹配。
- 非空字符串分支:
- 取出首字符
x和剩余部分xs,如果x等于目标字符c,就把当前这一次(+1)加上递归处理xs的结果(继续统计开头连续的c)。 - 如果
x不等于c,说明开头连续的c已经中断,直接返回0。
- 取出首字符
验证示例
length_char 'a' "aaabaa":前三个字符都是a,每次递归加1,到第四个字符b时返回0,最终结果是3,符合预期。length_char 'c' "cbcac":第一个字符是c,加1后递归处理剩余字符串,第二个字符是b不匹配,返回0,最终结果是1,符合预期。
如果你更习惯用if表达式,也可以写成这样(同样符合限制):
length_char :: Char -> String -> Int length_char c string = if string == [] then 0 else if head string == c then 1 + length_char c (tail string) else 0
内容的提问来源于stack exchange,提问作者user13744763
相关产品推荐
相关产品推荐

