用KMP和KMP改进算法求目标串的子串。
KMP
//使用next数组
#include <bits/stdc++.h>
using namespace std;
char a[1000];
char b[1000];
int nex[1000];
void get()
{
int i = 0, k = -1;
nex[i] = k;
while (i < strlen(b))
{
if (k == -1 || b[i] == b[k]) //无路可走 或者遇到相同的
{
nex[++i] = ++k;
}
else
k = nex[k]; //回溯
}
}
void kmp()
{
int ans = 0;
int i = 0, j = 0;
while (i < strlen(a))
{
if (j == -1 || a[i] == b[j]) //一样就走下一个
{
i++;
j++;
}
else
j = nex[j];
if (j == strlen(b)) //找到一个完整的
{
ans++;
j = nex[j];
}
}
cout << ans << endl;
}
int main()
{
cin >> a >> b;
get();
cout << "模式串出现次数为:";
kmp();
}
kmp改进
//因为nex表示的是最长前缀和后缀一样的数组
=====================================================
abac
abab //b与c匹配失败 会移动第一次出现的b 但是没必要 因为b == b 都是匹配不上的
======================================================
#include <bits/stdc++.h>
using namespace std;
char a[1000];
char b[1000];
int nex[1000];
void get()
{
int i = 0, k = -1;
nex[i] = k;
while (i < strlen(b))
{
if (k == -1 || b[i] == b[k]) //无路可走 或者遇到相同的
{
i++;
k++;
if(b[i] != b[k])
{
nex[i] = k;
}
else
{
nex[i] = nex[k];
}
}
else
k = nex[k]; //回溯
}
for (int i = 0; i <= strlen(b); i++)
cout << nex[i] << ' ';
cout << endl;
}
void kmp()
{
int ans = 0;
int i = 0, j = 0;
while (i < strlen(a))
{
if (j == -1 || a[i] == b[j]) //一样就走下一个
{
i++;
j++;
}
else
j = nex[j];
if (j == strlen(b)) //找到一个完整的
{
ans++;
j = nex[j];
}
}
cout << ans << endl;
}
int main()
{
cin >> a >> b;
get();
cout << "模式串出现次数为:";
kmp();
}
运行结果如下