今天在写kmp算法时出现了一个奇怪的问题:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void getNextVal(vector<int>& next,string& t)
{
next[0] = -1;
int i = 0;
int j = -1;
while (i < int(t.size()) - 1)
{
if (j == -1 || t[i] == t[j])
{
i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
}
int KMP(string s, string t)
{
vector<int> next(t.size());
getNextVal(next, t);
int i = 0;
int j = 0;
while (i < s.size() && j < t.size())//有问题
{
if (j == -1 || s[i] == t[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j >= t.size())
return i - j;
else
return -1;
}
int main()
{
string s = "abaccababc";
string t = "abab";
//int output = kmp(s, t);
int output = KMP(s, t);
cout << output << endl;
return 0;
}
在下图中的位置加一个断点:
然后添加监视:
很奇怪,这是怎么跳出上面的while循环的?
while (i < s.size() && j < t.size())
查博客发现size函数返回的时无符号类型size_t,但是j是有符号类型int,当j=-1时,对应的无符号是4294967295,于是退出了循环!!!
将代码改正之后程序运行正确:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void getNextVal(vector<int>& next,string& t)
{
next[0] = -1;
int i = 0;
int j = -1;
while (i < int(t.size()) - 1)
{
if (j == -1 || t[i] == t[j])
{
i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
}
int KMP(string s, string t)
{
vector<int> next(t.size());
getNextVal(next, t);
int i = 0;
int j = 0;
//下面时改正方法
int size1 = s.size();
int size2 = t.size();
while (i < size1 && j < size2)
{
if (j == -1 || s[i] == t[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j >= t.size())
return i - j;
else
return -1;
}
//int KMP(string s, string t)
//{
// vector<int> next(t.size());
// getNextVal(next, t);
// int i = 0;
// int j = 0;
// while (i < s.size() && j < t.size())
// {
// if (j == -1 || s[i] == t[j])
// {
// i++;
// j++;
// }
// else
// {
// j = next[j];
// }
// }
// if (j >= t.size())
// return i - j;
// else
// return -1;
//}
int main()
{
string s = "abaccababc";
string t = "abab";
int output = KMP(s, t);
cout << output << endl;
return 0;
}