KMP
1、构造next数组
next 数组是前缀表或者说是前缀表的变形,前缀表记录的是最长相同的前后缀的长度。
举个例子:aabaaf——>[0, 1, 0, 1, 2, 0]
常用的两种next数组
1、前缀表统一减一
- abaaf——>[0, 1, 0, 1, 2, 0]——>[-1, 0, -1, 0, 1, -1 ]
- 使用j = next[j]回退
- 代码
void get_next(int *next, const string &s)
{
int j = -1;
next[0] = j;
for (int i = 1; i < s.size(); i++) {
while (j >= 0 && s[i] != s[j+1]) {
j = next[j];
}
if (s[i] == s[j+1]) {
j++;
}
next[i] = j;
}
}
int get_str(string haystack, string needle)
{
if (needle.size() == 0) {
return 0;
}
int next[needle.size()];
get_next(next, needle);
int j = -1;
for (int i = 0; i < haystack.size(); i++) {
while (j >=0 && haystack[i] != needle[j+1]) {
j = next[j];
}
if (haystack[i] == needle[j+1]) {
j++;
}
if (j == needle.size() -1) {
return (i - needle.size() +1)
}
}
return -1;
}
2、直接使用前缀表
- aabaaf——>[0, 1, 0, 1, 2, 0]
- 使用j = next[j-1]回退
- 代码
void get_next(int *next, const string &s)
{
int j = 0;
next[0] = 0;
for (int i = 1; i < s.size(); i++) {
while (j > 0 && s[i] != s[j]) {
j = next[j-1];
}
if (s[i] == s[j]) {
j++;
}
next[i] = j;
}
}
int get_str(string haystack, string needle)
{
if (needle.size() == 0) {
return 0;
}
int next[needle.size()];
get_next(next, needle);
int j = 0;
for (int i = 0; i < haystack.size(); i++) {
while (j >0 && haystack[i] != needle[j]) {
j = next[j-1];
}
if (haystack[i] == needle[j]) {
j++;
}
if (j == needle.size()) {
return (i - needle.size() +1)
}
}
return -1;
}
建议
建议使用前缀表直接作为next数组,比较好理解