You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

子串索引不匹配问题:分析给定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");
        }
    }
}

修正点说明

  1. 移除循环自动递增i:把for循环的i++移到分支里控制,避免双重递增导致的跳步问题。
  2. 匹配失败时回溯:当字符不匹配时,将i调整为i - j + 1(回到这一轮匹配开始的下一个位置),同时把j重置为0,重新开始匹配。
  3. 优化循环终止条件:直接在for循环里判断j < str2Len,一旦子串匹配完成就立刻终止循环,减少无用操作。
  4. 处理大小写问题(可选):如果你需要忽略大小写匹配,可以把字符比较改成Character.toLowerCase(str.charAt(i)) == Character.toLowerCase(str2.charAt(j)),这样原示例中的UummbBerrrella和Umbrella就能匹配成功了。

内容的提问来源于stack exchange,提问作者jogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:44:11