子串索引不匹配问题:分析给定Java子串匹配代码的异常原因
子串匹配代码的索引不匹配问题分析与修复
先来看你提供的这段代码,它的目标是实现子串匹配,但确实存在明显的索引逻辑错误,导致无法正确完成匹配。
原代码的逻辑缺陷
首先贴出原代码方便分析:
import java.util.*; class String_pattern { public static void main ( String... arg ) { String str = "UummbBerrrella"; String str2 = "Umbrella"; int j = 0; for ( int i=0; i < str.length(); i++ ) { if ( j < str2.length() ) { if( str.charAt(i) == str2.charAt(j) ) { System.out.println( i + " " + j ); i++; j++; } else { i++; } } } if( j == str2.length() ) System.out.println( " true " ); else System.out.println( " false " ); } }
主要问题集中在这几点:
- 索引跳步错误:for循环本身每次迭代会执行
i++,但你在if和else分支里又手动加了i++,这意味着每次循环i实际增加了2,直接跳过了主串中一半的字符,完全无法完整遍历主串,自然会错过匹配机会。 - 匹配失败未回溯状态:当主串当前字符和子串不匹配时,你没有重置子串的索引
j为0,也没有将主串索引回退到上一次尝试匹配的起始位置的下一位,而是继续往后跳,导致彻底丢失了重新匹配的可能。 - 冗余的循环执行:当
j已经等于子串长度(说明已经匹配完成),循环仍然会继续执行,做了很多无用的遍历。
修正后的代码实现
下面是修复后的版本,实现了正确的暴力子串匹配逻辑,同时保留了原代码的打印匹配索引的功能:
import java.util.*; class String_pattern { public static void main ( String... arg ) { String str = "UummbBerrrella"; String str2 = "Umbrella"; int j = 0; int strLen = str.length(); int str2Len = str2.length(); for (int i = 0; i < strLen && j < str2Len; ) { if (str.charAt(i) == str2.charAt(j)) { System.out.println(i + " " + j); i++; j++; } else { // 匹配失败,回溯:i回到上一次匹配起始位置的下一位,j重置为0 i = i - j + 1; j = 0; } } if (j == str2Len) { System.out.println("true"); } else { System.out.println("false"); } } }
修正点说明
- 移除循环自动递增i:把for循环的
i++移到分支里控制,避免双重递增导致的跳步问题。 - 匹配失败时回溯:当字符不匹配时,将
i调整为i - j + 1(回到这一轮匹配开始的下一个位置),同时把j重置为0,重新开始匹配。 - 优化循环终止条件:直接在for循环里判断
j < str2Len,一旦子串匹配完成就立刻终止循环,减少无用操作。 - 处理大小写问题(可选):如果你需要忽略大小写匹配,可以把字符比较改成
Character.toLowerCase(str.charAt(i)) == Character.toLowerCase(str2.charAt(j)),这样原示例中的UummbBerrrella和Umbrella就能匹配成功了。
内容的提问来源于stack exchange,提问作者jogi
相关产品推荐
相关产品推荐

