匹配字符串常见的算法是,匹配字符串在被匹配字符串上一个一个向下移动,如果遇到不匹配,再回退回来,继续匹配下去。
举例:
被匹配字符串S "acabaabaabcacaabc"
匹配字符串(也叫模式字符串)P "abaabcac"
好比现在字符串到acabaabaabcacaabc(i=7)
abaabcac (j=5)
现在遇到不匹配时,P字符的j退到0位置,S字符i退到3位置
现在可以看一下KMP算法,KMP算法的思路是在S字符串的i值不回退(就是向上边的i值还是7),只是将P中循环的j值匹配到j为2的位置,为什么是这样呢?
可以看一下P字符串的规律
abaabcac
在c之前两个ab都是相同的,也就是说在c遇到不匹配的时候c前边的ab如果再来匹配的时候,在P前边的ab肯定能和c紧挨着的ab匹配上,那就等下次匹配的时候P开始的ab就不需要匹配了,将j直接移到j=2的位置a处开始匹配就可以了。这里仅仅是人工的来看,下边说一下算法的思路,算法比较专业的说法就是给P的每一位值计算出如果不匹配的时候这个j值应该是多少,向上边的讨论中,遇到在c这里不匹配了,再匹配的时候j的值应该是2.使用书本上的说法就是把这些值先放到next数组中,next数组中存放的就是j要
看到上边的分析,应该可以有点思路了吧。
就是在遇到不匹配的地方,将前边的字符串分为两半,像上边的abaab,然后用最大的长度将前后两部分分开,abaab,这里j就是匹配的值+1就是2。
算法初始化next[0] = -1;
算法的代码
void init_nextv()
{
int i=0,j=-1;
int p_len; /*模式串的长度*/
p_len=strlen(p);
nextv[0]=-1;
while(i<p_len-1)
{
if(j==-1 || p[i]==p[j])
{
++i;++j;
if(p[i]!=p[j])nextv[i]=j;
else nextv[i]=nextv[j];
}
else j=nextv[j];
}
}
KMP算法最主要的是这个next函数的创建,讲的还不是很清楚,后续工作还要继续修改