int KMP_find(string s, string pattren,int begin=0) //begin表示开始下标
{
vector<int>next = KMP_next(pattren); //得到next数组
int i = begin;
int j = 0;
while (i < s.size()&&j<pattren.size())
{
while (j>=0&&pattern[j]!=s[i])//如果相等,i和j都往后移动
{<span style="white-space:pre"> </span> //如果不相等,两种情况,第一种,i之前的部分需要重新比较j=next[j],重新进入while循环比较,i还是当前位
j = next[j];<span style="white-space:pre"> </span>//第二种情况,i之间的不需要重新比较,j=-1,跳出里层while循环,i往后移动一位,j自加1后等于0,指向第一位<span style="white-space:pre"> </span>
}
i++,j++;
}
if (j >= pattren.size()) //外层while循环结束,只有两种可能,第一种i超出s的长度,或者j超出pattern的长度
return i - begin; //只要j超出,则可表示完成了匹配,返回s中匹配的起始位置
return -1; //否者返回-1
}
vector<int> KMP_next(string match) //发生第一种情况的时候,j应该重新移动到哪一个位置
{
vector<int>next(match.size());
next[0] = -1; //第一位为-1,作为j跳出循环的条件
int j = 0, k = -1;
while (j<match.size() - 1)
{ //每个j当前位置的值,都是对j-1的判断
while (k >= 0 && match[k] != match[j])//如果相等则跳出循环对j赋值
{ //如果不相等,k 到前一个位置,
k = next[k]; // 或者k=-1跳出循环
// 或者重新作比较
}
k++, j++;
next[j] = k; //第二位为0
}
return next;
}
next改进版:
vector<int> KMP_next(string match)
{
vector<int>next(match.size());
next[0] = -1; //第一位为-1,作为j跳出循环的条件
int j = 0, k = -1;
while (j<match.size() - 1)
{
while (k >= 0 && match[k] != match[j])
{
k = next[k];
}
k++, j++;
if (match[j] != match[k]) //此时应该给当前位置j赋值,如果此时比较的两位不相等,那么正常赋值
next[j] = k;
else
{
next[j] = next[k]; //否则直接把next[k]赋值
}
}
return next;
}
仍然可以改进的地方:前面可以连续出现-1