KMP字符串匹配
题:28. 找出字符串中第一个匹配项的下标 https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/
给你两个字符串 haystack
和 needle
,请你在 haystack
字符串中找出 needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle
不是 haystack
的一部分,则返回 -1
。
示例 1:
输入:haystack = "sadbutsad", needle = "sad" 输出:0 解释:"sad" 在下标 0 和 6 处匹配。 第一个匹配项的下标是 0 ,所以返回 0 。
题解见注释
1 class Solution { 2 public: 3 int strStr(string haystack, string needle) { 4 /* 5 Knuth-Morris-Pratt(KMP)算法,可在 O„m + n” 时间完成匹配。 6 1.寻找needle每个索引为子串的最长相等前后缀数组:前缀是指不含尾字母的所有子串,后缀是指不含首字符的所有子串,单个字符没有前后缀 7 如needle=bbcbbd,b:0;i=1,子串bb:1(因为前缀b后缀b相等);i=2,子串bbc:0(前缀b、bb,后缀c、bc没有相等的);i=3,bbcb:1 8 (前缀b、bb、bbc,后缀c、cb、bcb,只有b相等);i=4,bbcbb:2(前缀b、bb、bbc、bbcb,后缀b、bb、cbb、bcbb,最长是bb,长度2) 9 i=5,bbcbbd:0。求得各个下标的最长相等前后缀构成一Next表,用于指导匹配时回朔。 10 2.匹配,根据next=[0,1,0,1,2,0]指导回退到一个位置上继续匹配 11 如haystack=bbcbbcbbd,当匹配到bbcbbc时,仅最后一个字符j=5(c)和i=5(d)d不等,这时回退到i=0匹配计算量太大,而到前一个字符b是相等的, 12 b对应的相等前缀是2,也就是说匹配到j=5(c)时,前边有两个bb是相等的,这时只需回到i=2时继续匹配就可以,i=2来源于next[5-1] 13 */ 14 //1计算next数组,求最长相等前后缀 15 int n = needle.size(); 16 vector<int> next(n, 0); // 首字符的前缀肯定为0 17 int j = 0; // 指向前缀的位置,i则指向每个待计算的下标 18 for (int i = 1; i < n; ++i) { 19 while(j > 0 && needle[j] != needle[i]) { // 只要不相等,j回退到前一个字符比较,或者已为0(当前i没有相等的) 20 j = next[j - 1]; // 这里要回到上一个字符对应的最长前缀才行, 21 // 比如adcadde,检查到i=5(d,倒数第一个d),此时j=2(c)的位置,此时不等,j不应该回到上一个j=1(d),而是d对应的next[1]=0 22 } 23 if (needle[j] == needle[i]) { 24 ++j; 25 } 26 next[i] = j; 27 } 28 29 // 回溯匹配 30 for (int j = 0, i = 0; j < haystack.size(); ++j) { 31 // 原理写成了if,haystack=abbababbabbbabaaa,next=abbabbbabaa会出现回溯一次后,i=2(b)继续匹配,此时是不等的,还需继续回溯 32 while (haystack[j] != needle[i] && i > 0) { // 这里是while,不是if 33 i = next[i - 1]; 34 } 35 if (haystack[j] == needle[i]) { 36 if (i == n - 1) return j - i; 37 ++i; 38 } 39 } 40 return -1; 41 } 42 };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!