字符串匹配—朴素模式匹配
基本思想
把模式与目标逐一进行比较(首位置开始),直到碰到不匹配的字符为止(模式右移一位再次开始匹配)
算法可在第一个匹配或是目标的结束处停止
算法过程
设T= T0T1, T2, …,Tn,P = p1, p2, …, pm
j为指向T中字符的下标指针,i为指向P中字符的下标指针
匹配成功 (p1 = Tj , p2 = Tj+1 , …, pm = Tj+m-1 )
即,substr(T, j, m)
匹配失败 (pi ≠ Tj) 时,将P右移再行比较
尝试所有的可能情况
效率分析
假定目标T的长度为n,模式P长度为m,且 m ≤ n 。在最坏的情况下,每一次循环都不成功,则一共要进行比较(n-m+1)次。每一次“相同匹配”比较所耗费的时间,是P和T逐个字符比较的时间,最坏情况下,共m次。
因此,整个算法的最坏时间开销估计为O(mn)
朴素算法的问题:回溯
朴素算法之所以效率不高的原因在于匹配过程中目标串有回溯,且这些回溯并非必要
e.g.,
由1)可知: P5 ≠ T5, P0=T0, P1 = T1,同时由 P0 ≠P1可得知P0≠T1 故将 P 右移一位后第2)趟比较一定不等; 比较冗余
那么把P右移几位合适? 既能消除冗余比较又保证不丢失配串呢?
代码实现
int NaiveStrMatching(string T, string P) {
int i=0; //模式的下标变量
int j=0; //目标的下标变量
int plen = p.length(); //模式的长度
int tlen= T.length(); //目标的长度
if(tLen < plen) //如果目标比横式烟,匹配无法成功
return (-1);
while(i<tlen){ //反复比较对应字符来开始匹配
if (T[j +i]==P[j+1]) {
i++;
}else{ //匹配失败,還8,门下移一位。
i =0;
j++;
break;
}
}
if(i>=pLen){
return (j - pLen+1);
} else {
return (-1);
}
}