模式匹配问题,即字符串的匹配,int index(String t,String p),求p在t中第一次出现的位置。如何高效地匹配?先来讨论朴素的回溯的模式匹配。例如,设t=“abbaba”,p=“aba”,p的长度为6(plen=6),t的长度为3(tlen=3)。匹配过程如下:
算法如下:
int index(string p, string t)
{
int i = 0, j = 0; //i,j分为p,t串当前字符的下标
while(i<p->n && j<t->n){ //反复比较
if(p->c[i] == t->c[j]){
i++; j++; //继续匹配下一个字符
}
else{
j = j - i + 1; //p,t串的i,j回溯,即重新开始下一次匹配
i = 0;
}
}
if(i >= p->n)
return(j - i +1); //匹配成功,返回p中第一个字符在t中的序号
else
return 0; //匹配失败
}
这种算法效率不高,在最坏的情况下,每趟比较都在最后出现不等,最多比较 tlen-plen+1 趟,总比较次数为 plen×(tlen-plen+1),由于在一般情况下plen<<tlen,所以算法的运行时间为O(plen× tlen)。
对于上图的匹配过程,由(a)可知:p0=t0,p1=t1,p2!=t2,
由p0!=P1可知p0!=t1,将p右移一位后(b)的比较一定不等;
由p0==p2可知p0!=t2,将p再右移一位后(c)的比较一定不等;
因此,由(a)便可直接将p右移3位跳到(d),从p0和t3开始作比较,很快可以匹配成功。这样的匹配过程对字符串 t 就消除了回溯。
这种快速的算法也就是,在右移若干位后,立即用p串中的一个新的字符Pk(k<i)和tj