/* P为模式串,下标从0开始 */
void GetNext(string P, int next[]) ///优化前next计算结果
{
int p_len = P.size();
int i = 0; //P的下标
int j = -1;
next[0] = -1;
while (i < p_len)
{
if (j == -1 || P[i] == P[j])
{
i++;
j++;
next[i] = j;
printf("j1=%d\n",j);
}
else{
j = next[j];
printf("j2=%d\n",j);
}
}
for(i=0;i<p_len;i++){
printf("%d ",next[i]);
}
printf("\n");
}
void GetNextval(string P, int nextval[]) ///优化后的next()结果
{
int p_len = P.size();
int i = 0; //P的下标
int j = -1;
nextval[0] = -1;
while (i < p_len)
{
if (j == -1 || P[i] == P[j])
{
i++;
j++;
if (P[i] != P[j])
nextval[i] = j;
else
nextval[i] = nextval[j]; //既然相同就继续往前找真前缀
}
else
j = nextval[j];
}
}
/* 在S中找到P第一次出现的位置 */
int KMP(string S, string P, int next[])
{
//GetNext(P, next);
GetNextval(P,next);
int i = 0; //S的下标
int j = 0; //P的下标
int s_len = S.size();
int p_len = P.size();
while (i < s_len && j < p_len)
{
if (j == -1 || S[i] == P[j]) //P的第一个字符不匹配或S[i] == P[j]
{
i++;
j++;
}
else
j = next[j]; //当前字符匹配失败,进行跳转
}
if (j == p_len) //匹配成功
return i - j;
return -1;
}
int main()
{
int next[100] = { 0 };
cout << KMP("bbc abcdab abcdabcdabde", "abcdabd", next) << endl; //15
//GetNext("abcdabd", next);
return 0;
}
reference:https://www.61mon.com/index.php/archives/183/
经典的字符串模式匹配算法KMP算法
最新推荐文章于 2020-10-16 00:28:39 发布