Java实现凯撒密码的code方法测试不通过,求排查错误原因
问题根源
- 核心错误是正则匹配的对象错误:你在遍历单个字符的循环里,给Matcher传入的是整个输入字符串text,而不是当前遍历到的单个字符
character。你的正则规则是匹配单个字母或.,长度大于1的字符串必然匹配失败,所以所有非单字符输入都会直接走else分支返回原内容,这就是测试用例vaca.zoologico输出原字符串的原因。 - 次要逻辑错误:你将
.也纳入了需要偏移的正则匹配范围,按现有逻辑匹配到.后会执行字母偏移计算,导致.被转成错误的字母,不符合测试用例中符号保留的预期。 - 性能优化点:Pattern不要放在循环内部重复创建,每次循环都编译正则会严重浪费性能,应该提前在循环外编译好。
修复后代码
// 提前编译正则,仅匹配大小写字母,仅编译一次 private static final Pattern LETTER_PATTERN = Pattern.compile("^[a-zA-Z]$"); public String code(String text, int distance){ if (distance < 0){ return null; } // 距离提前取模,避免循环内重复计算 distance = distance % 26; StringBuilder result = new StringBuilder(); for (char character : text.toCharArray()) { // 传入当前单个字符做正则匹配 Matcher mat = LETTER_PATTERN.matcher(String.valueOf(character)); if (mat.matches()) { // 保留原字符大小写属性 boolean isUpperCase = Character.isUpperCase(character); char lowerChar = Character.toLowerCase(character); int originalAlphabetPosition = lowerChar - 'a'; int newAlphabetPosition = (originalAlphabetPosition + distance) % 26; char newCharacter = (char) ('a' + newAlphabetPosition); // 还原原字符大小写 result.append(isUpperCase ? Character.toUpperCase(newCharacter) : newCharacter); } else { // 非字母字符直接保留,包括.、空格、数字、符号等 result.append(character); } } return result.toString(); }
修复验证
修复后即可通过所有单元测试:
- 单字符偏移逻辑和原有正确逻辑保持一致
- 长字符串中的字母会正常偏移,符号、空格、数字全部原样保留
- 大小写特性保留,不会把所有输入都转为小写输出
- 距离大于26的场景通过提前取模正常兼容
内容的提问来源于stack exchange,提问作者icatalan
相关产品推荐
相关产品推荐

