您的位置:首页 > 其它

KMP(内含next数组讲解) —— 剪花布条 ( HDU 2087 )

2016-07-14 18:13 113 查看
关于KMP算法前缀next最同俗易懂的解释请看:

http://blog.csdn.net/yearn520/article/details/6729426

next数组代码:(将第一位赋值为-1,无重复位置赋值为0,重复位一次递增)

void SetNext()//子串的next数组,如果只看代码的话,很难得出值的确定方法。
{
int i=0,j=-1;
Next[0]=-1;
while(i<M)
{
if(j==-1||b[i]==b[j])//b为模式数组
{
i++; j++;
Next[i]=j;
}
else
j=Next[j];
}
}


KMP匹配代码:(依赖上面的SetNex()函数)

int Kmp()
{
int i=0,j=0;
SetNext();
while(i<N)//a为目标数组
{
if(j==-1||a[i]==b[j])//这里j=-1的情况就是第一个字符不匹配的情况。
{
i++;j++;
}
else
j=Next[j];//如果匹配不上,这里回溯j,
if(j==M)//如果匹配成功了。
return i-j+1;//回溯j最终的位子。
}
return -1;
}


练习:

http://acm.hdu.edu.cn/showproblem.php?pid=2087

分析&题解:

很裸的KMP,计算目标字符串中含有多少个子串。修改一下KMP函数,每匹配完成一次,计数++,直到匹配不了为止。

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cmath>

using namespace std;
int N,M;
char a[1234];
char b[1234];
int Next[1234];
int cnt ;
void SetNext()//子串的next数组,如果只看代码的话,很难得出值的确定方法。
{
int i=0,j=-1;
Next[0]=-1;
while(i<M)
{
if(j==  -1||b[i]==b[j])
{
i++; j++;
Next[i]=j;
}
else
j=Next[j];
}
}
void Kmp()
{
int i=0,j=0;
SetNext();
while(i<N)
{
if(j== -1||a[i]==b[j])//这里j=-1的情况就是第一个字符不匹配的情况。
{
i++;j++;
}
else
j=Next[j];//如果匹配不上,这里回溯j,
if(j==M)//如果匹配成功了。
{
j = 0;
cnt++;
}
}
return ;
}

int main()
{
while(scanf("%s", &a) )
{
if(a[0] == '#')
break;
cnt = 0;
scanf("%s", &b);
N = strlen(a);
M = strlen(b);
SetNext();
Kmp();
cout << cnt << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  kmp ACM 算法 HDU-2087