#include <iostream>
#include <string>
using namespace std;
//获取next数组
int* getNext(string T)
{
int len = T.size(); //获取T的长度
int* next = new int[len]; // 声明next数组
int j = 0; // T后缀下标
int k = -1; // T前缀下标
next[0] = -1;
while (j < len-1)
{
if (k == -1 || T[j] == T[k]) //k==-1时,短路
{
j++;
k++;
next[j] = k;
}
else{
k = next[k]; //前后缀失配,进行回溯
}
}
return next;
}
// KMP算法,在 S 中找到 T 第一次出现的位置
int KMP(string S, string T) // S为主串,T为模式串
{
int* next = getNext(T);
int i = 0; // S下标
int j = 0; // T下标
int s_len = S.size();
int t_len = T.size();
while (i < s_len && j < t_len)
{
if (j == -1 || S[i] == T[j]) //T 的第一个字符不匹配或S[i] == T[j]
{
i++;
j++;
}
else{
j = next[j]; // 当前字符匹配失败,进行跳转
}
}
if (j == t_len){
return i - j; // 匹配成功
}
return -1;
}
int main()
{
string S = "bcabcdababcdabcdabde";
string T = "abcdabd";
int num = KMP(S, T);
cout << num <<endl;
return 0;
}