Haskell编写首字母缩略词函数出错,如何从"apple apple"得到正确结果"aa"
问题根因
- 逻辑运算符优先级错误:Haskell 中
&&优先级高于||,你写的第三个判断条件没有加括号,实际执行逻辑和你预期的「x和y均为字母」完全不符,导致大部分字母场景都误触发该分支,每遍历两个字母就取第一个,自然会输出apape这类错误结果。 - 分支顺序冗余冲突:第一个分支已经处理了
x == ' '的场景,后续第四个判断x == ' ' && ...的分支永远不会触发,属于无效逻辑。 - 核心逻辑偏差:首字母缩略词的核心是取每个单词的第一个字母,你当前的逻辑是只要相邻都是字母就保留前一个,等于把单词内部的字母也挨个取了,完全不符合缩略词生成规则。
修正方案
首先封装字母判断逻辑简化代码,再调整分支顺序和判断逻辑,确保只取每个单词的首字母:
acronym :: String -> String acronym [] = [] -- 单个字母直接返回,非字母返回空 acronym [x] = if isAlpha x then [toUpper x] else [] acronym s@(x:xs) -- 开头是字母,保留为第一个单词的首字母,跳过后续同单词的所有字母 | isAlpha x = toUpper x : acronym (dropWhile isAlpha xs) -- 开头是空格,跳过空格继续处理 | otherwise = acronym xs where isAlpha c = c `elem` ['a'..'z'] || c `elem` ['A'..'Z'] toUpper c | c `elem` ['a'..'z'] = toEnum (fromEnum c - 32) | otherwise = c
如果你不需要自动转大写,删除toUpper相关逻辑即可。输入"apple apple"时,上述代码会返回"AA",符合首字母缩略词的预期输出。
若要保留原有递归双字符匹配的写法,调整如下:
acronym :: String -> String acronym [] = [] acronym [x] = if isAlpha x then [x] else [] acronym (x:y:xs) -- 空格后接字母,保留字母作为下一个单词首字母 | x == ' ' && isAlpha y = y : acronym xs -- 普通空格直接跳过 | x == ' ' = acronym (y:xs) -- 字母后接空格,跳过当前字母和空格 | isAlpha x && y == ' ' = acronym xs -- 字母后接字母,仅跳过当前字母(同单词内非首字母不需要保留) | isAlpha x && isAlpha y = acronym (y:xs) | otherwise = acronym (y:xs) where isAlpha c = c `elem` ['a'..'z'] || c `elem` ['A'..'Z']
内容的提问来源于stack exchange,提问作者Ethan Lim
相关产品推荐
相关产品推荐

