
本文介绍一种高效、可靠的算法,用于在由多个字符串片段组成的列表中查找跨片段目标子串(如[{searched_placeholder}])的起始和结束位置索引,并返回其在原始列表中的最小覆盖区间。
本文介绍一种高效、可靠的算法,用于在由多个字符串片段组成的列表中查找跨片段目标子串(如[{searched_placeholder}])的起始和结束位置索引,并返回其在原始列表中的最小覆盖区间。
在实际开发中,常遇到文本被预分割为 List<string></string> 的场景(如模板引擎、富文本解析或流式内容处理),而待搜索的目标字符串(例如占位符 [{searched_placeholder}])可能恰好横跨多个列表元素。此时,不能简单使用 String.contains() 或逐项匹配,而需确定该子串首次完整出现所覆盖的最小连续子列表范围——即起始索引 startIdx 和结束索引 endIdx。
核心思路是:构建累积拼接的字符串流,在拼接过程中动态判断目标子串是否首次“完全可见”;再反向收缩前缀,精确定位起始位置。以下为优化后的实现方案:
public static int[] findSubstringSpan(List<string> fragments, String target) {
if (fragments == null || target == null || fragments.isEmpty()) {
return new int[]{-1, -1};
}
StringBuilder sb = new StringBuilder();
int endIndex = -1;
// 第一遍:找到目标子串首次完整出现时的结束索引
for (int i = 0; i 0) {
startIndex = i;
break;
}
if (i == endIndex && temp.indexOf(target) != -1) {
startIndex = i; // 全部在最后一个片段中
}
}
return new int[]{startIndex, endIndex};
}</string>
✅ 使用示例:
List<string> str = new ArrayList();
str.add("This is a ");
str.add("[{searched");
str.add("_placeholder}]");
str.add(" in this string.");
int[] span = findSubstringSpan(str, "searched_placeholder");
System.out.println("Start index: " + span[0] + ", End index: " + span[1]);
// 输出:Start index: 1, End index: 2</string>
⚠️ 注意事项:
- 该算法时间复杂度为 O(n·m)(n 为列表长度,m 为平均片段长度),适用于中小规模数据;若性能敏感,可改用 KMP 或 Rabin-Karp 预处理目标串,但需重写匹配逻辑。
- 严格区分“子串存在”与“精确边界”:本方案返回的是覆盖目标子串所需的最短连续索引区间,不保证目标串起始字符一定位于
fragments[startIndex]开头,仅保证其跨越startIndex到endIndex(含)。 - 若目标串为空或列表为空,方法安全返回
[-1, -1],调用方应做空值校验。
该方案兼顾可读性与鲁棒性,可直接集成至模板解析器、动态文本替换等业务模块中。










