#include <iostream>
#include <string>
#include <vector>
using namespace std;
void Getnextval(string s, vector<int> &nextval)
{
int n = s.length();
nextval[1] = 0;
int i = 1;
int j = 0;
while (i < n)
{
if (j == 0 || s[i] == s[j])
{
i++;
j++;
if (s[i] != s[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
}
else
j = nextval[j];
}
}
int Kmp(string str, string sub, int pos)
{
vector<int> nextval;
nextval.resize(sub.length() + 1);
Getnextval(sub, nextval);
int lenstr = str.length();
int lensub = sub.length();
if (lenstr == 0 || lensub == 0)
return -1;
if (pos < 0 || pos > lenstr)
return -1;
int i = pos;
int j = 0;
while (i < lenstr && j < lensub)
{
if (j == 0 || str[i] == sub[j])
{
i++;
j++;
}
else
{
j = nextval[j];
}
}
if (j >= lensub)
return i - lensub;
else
return -1;
}
int main()
{
char c = 'y';
while (c == 'y')
{
string str;
string sub;
cout << "请输入主串str(#开头): ";
getline(cin, str);
cout << "请输入子串sub(#开头): ";
getline(cin, sub);
vector<int> nextval;
nextval.resize(sub.length() + 1);
Getnextval(sub, nextval);
int result;
int pos;
cout << "请输入pos(在主串第pos个位置查询): ";
cin >> pos;
result = Kmp(str, sub, pos);
cout << "结果是: " << result;
cout << endl << "是否继续? y/n" << endl;
cin >> c;
getchar();
}
return 0;
}