字符串中子串多次出现的索引查找代码原理及实现咨询
字符串子串索引查找:原代码解析与优化方案
先来看你给出的这段代码,我先拆解它的工作逻辑,再说说怎么修改才能实现「找出子串在母串中所有出现的索引」的需求。
原代码的工作原理
先把代码贴出来方便分析:
String input = "asdesdu"; String largestStr = "sd"; String tempInput = input; while (tempInput.indexOf(largestStr) != -1) { int index = tempInput.indexOf(largestStr); tempInput = tempInput.substring(index + 1); }
这段代码的思路是用临时字符串逐步缩小查找范围:
- 先把原串
input复制给tempInput,避免修改原字符串; - 循环判断:只要临时串里还能找到目标子串
largestStr,就继续执行; - 每次循环里,先拿到子串在当前临时串里的起始索引,然后把临时串从这个索引的下一个位置截取,相当于砍掉已经查过的部分,继续在剩余内容里找。
但这段代码有个核心问题:它完全没有记录任何找到的索引,就算你想加记录逻辑,直接用index也不对——因为每次截取后,临时串的索引和原串的索引已经偏移了,比如第一次找到的sd在原串里是索引1,但临时串截取后变成esdu,这里的索引和原串完全对应不上。
完善代码:实现查找所有子串索引
要正确记录所有原串索引,我们不需要截取原串,而是用一个变量记录下一次查找的起始位置,直接在原串上反复查找即可。下面是优化后的代码:
import java.util.ArrayList; import java.util.List; public class SubstringIndexFinder { public static void main(String[] args) { String input = "asdesdu"; String targetSubStr = "sd"; // 用来存储所有找到的起始索引 List<Integer> allIndices = new ArrayList<>(); int currentSearchPos = 0; // 从currentSearchPos位置开始查找子串,找不到就返回-1,循环结束 while ((currentSearchPos = input.indexOf(targetSubStr, currentSearchPos)) != -1) { // 把找到的原串索引加入集合 allIndices.add(currentSearchPos); // 移动查找起点:如果要避免重叠匹配(比如子串"aa"在"aaaa"里只找0和2),就加子串长度 // 如果允许重叠匹配(找0、1、2),就改成currentSearchPos + 1 currentSearchPos += targetSubStr.length(); } // 输出结果 System.out.println("子串\"" + targetSubStr + "\"在母串中的所有起始索引:"); for (int idx : allIndices) { System.out.println(idx); } } }
优化后代码的逻辑解释
- 用集合存储索引:用
List<Integer>保存所有找到的起始索引,方便后续使用或输出; - 跟踪查找位置:
currentSearchPos记录下一次开始查找的位置,初始值为0; - 带起始位置的查找:
input.indexOf(targetSubStr, currentSearchPos)会从指定位置开始查找子串,返回的是原串中的真实起始索引,完全不需要额外的偏移计算; - 更新查找位置:每次找到后,把
currentSearchPos更新为「当前索引 + 子串长度」,这样下一次查找就从当前子串结束的位置开始,避免重复匹配同一个子串;如果你的需求是允许重叠匹配(比如找"aa"在"aaaa"里的所有出现:0、1、2),只需要把这行改成currentSearchPos += 1就行; - 输出结果:最后遍历集合,把所有找到的索引打印出来。
内容的提问来源于stack exchange,提问作者Cruskits
相关产品推荐
相关产品推荐

