KMP算法(有限状态机思路):https://zhuanlan.zhihu.com/p/83334559
//KMP 串的模式匹配
#include <iostream>
#include <string.h>
using namespace std;
// BF算法
int search(string pat, string txt) {
int M = pat.length();
int N = txt.length();
for (int i = 0; i <= N - M; i++) {
int j;
for (j = 0; j < M; j++) {
if (pat[j] != txt[i+j])
break;
}
// pat 全都匹配了
if (j == M) return i;
}
// txt 中不存在 pat 子串
return -1;
}
// KMP算法 有限状态机思想
// dp数组用来存储状态转移图 [j][可能字符] = 下一个状态(+1或者回退)
int dp[100010][26] = {0};
// bp因此只与子串有关 bp的构建
void Build_dp(char* pat)
{
int M = strlen(pat);
int j = 0;
for ( int i= 0; i < 100010; i++)
for(int j = 0; j < 26;j++)
dp[i][j] = 0;
// 动态规划思想 dp在状态0下的状态切换易得
dp[0][int(pat[0])- 'a'] = 1; // 初始状态切换
int X = 0;// 影子状态 j在c字符处的状态切换与X一致(如果要回退时)
for(int j = 1; j < M; j++)
{
for(int c = 0;c<26;c++) // 假设所有字符都要回退
dp[j][c] = dp[X][c];
// 可导致状态前进的字符 目标状态+1
dp[j][int(pat[j])- 'a'] = j+1;
// 确保X是与J具有最长相同前缀(所以x要落后于j) X称j的影子状态 X始终落后于j的状态
X = dp[X][int(pat[j])- 'a'];
}
}
int search(char* txt,char* pat)
{
int N = strlen(txt);
int j = 0;
int M = strlen(pat);
Build_dp(pat);
for(int i = 0; i <N; i++)
{
j = dp[j][int(txt[i])-'a'];
if(j == M) return i-M+1;
}
return -1;
}
int main()
{
char txt[1000010];
cin >> txt;
int result = -1;
int n;
cin >> n;
while (n--)
{
char pat[100010];
cin >> pat;
result = search(txt,pat);
if(result != -1)
cout << txt+result <<endl;
else
cout <<"Not Found\n";
}
return 0;
}