Java子串匹配异常:末尾子串的最后一个字符未被识别
问题原因分析
你的代码在处理主字符串末尾的子串时出现统计遗漏,核心问题在于当前的逐个字符匹配逻辑存在边界场景漏洞:
- 当子串刚好匹配主串末尾的连续字符时,虽然最后一个字符匹配成功后会触发计数,但如果主串中存在部分匹配后中断的情况,可能导致末尾的完整匹配被忽略(比如你示例中的主串
jre?jokllljdg?kajf?b?argujbvabvaz,末尾的bvaz实际存在,但原代码可能因为之前的匹配重置操作,在处理到末尾的b时没有正确初始化匹配状态)。 - 另外,代码存在隐藏的数组越界风险:当
num递增到等于子串长度时,sub_chars[num]会访问超出数组索引的位置,虽然你在匹配完成后立即重置num,但极端情况下仍可能触发异常。
修复方案
改用基于起始位置遍历的方式,直接检查每个可能的子串起始点是否匹配,逻辑更清晰,能覆盖所有边界场景(包括末尾匹配):
public class Main { public static void main(String[] args) { String full_string = "jre?jokllljdg?kajf?b?argujbvabvaz"; String sub_strings[] = {"jbva","eljz","klll","gujb","jrex","bvaz"}; for (String sub : sub_strings) { findTheSubString(full_string, sub); } } public static void findTheSubString(String fullString, String subString) { int fullLen = fullString.length(); int subLen = subString.length(); int matchCount = 0; // 子串为空或比主串长,直接返回无匹配 if (subLen == 0 || subLen > fullLen) { System.out.println("No Matches!"); return; } // 遍历所有可能的起始索引 for (int start = 0; start <= fullLen - subLen; start++) { boolean isMatch = true; for (int i = 0; i < subLen; i++) { char fullChar = fullString.charAt(start + i); char subChar = subString.charAt(i); // 匹配规则:主串是?,或大小写不敏感相等 if (fullChar != '?' && Character.toUpperCase(fullChar) != Character.toUpperCase(subChar)) { isMatch = false; break; } } if (isMatch) { matchCount++; } } if (matchCount == 0) { System.out.println("No Matches!"); } else { System.out.println("found " + matchCount + " substrings!"); } } }
修复说明
- 遍历逻辑优化:通过遍历主串中所有可能的子串起始位置(从
0到fullLen - subLen),确保不会遗漏任何可能的匹配,包括主串末尾的子串。 - 匹配逻辑清晰:对每个起始位置,逐个字符对比,只要有一个字符不匹配就终止当前检查,避免无效操作。
- 边界条件处理:提前判断子串为空或过长的情况,直接返回结果,避免不必要的循环。
- 消除越界风险:所有字符访问都通过合法的索引范围,不会出现数组越界异常。
运行修改后的代码,bvaz会被正确统计为1次匹配,其他子串的匹配结果也会准确输出。
内容的提问来源于stack exchange,提问作者Joseph McTigue
相关产品推荐
相关产品推荐

