蛮力匹配
蛮力匹配算法一:
int match(char *p,char *T){
size_T n =strlen(T),i=0;
size_T m = strlen(p),j=0;
while(i<n&&j<m){
if(T[i]==P[j]){i++;j++;}
else {i=i-j+1;j=0;}
return i-j;
}
}
蛮力匹配算法二:
int match(char *p,char *T){
size_T n =strlen(T),i=0;
size_T m = strlen(p),j;
for(i=0;i<n-m+1;i++)
for(j=0;j<m,j++)
if(T[i+j]!=p[j]) break;
if(m<=j)break;
}
KMP算法
改进方向
1.可大幅度向后滑动模式串
2.可避免重复比对
主算法:通过查询构造好的next表,当遇到不匹配的字符时,将模式串后移动几个单位,在之前不匹配位置重新进行一轮新的匹配过程
实例:
Next[]表
快速移动+避免回退
快速移动:模式串快速移动的条件是,模式串中前后缀中存在两段相同的字符串P[0,t]和P[j-t,j]
避免回退:KMP算法选取最大的那个t
Next[0]=-1,即在模式串前面建立一个和任何字符都匹配的哨兵,使得可以解决j=0的情况,即解决模式串中没有重复字符段的情况
构造Next[]表
//KMP算法主函数
int match(char *p,char *T){
int *next = buildNext(p);
int n =(int)strlen(T),i=0;
int m =(int)strlen(P),j=0;
while(j<m && i<n){
if(0>j||T[i]==P[j]){//若匹配
i++;j++;}//则携手共进
else //否则,根据Next[]表P右移,T不回退
j=next[j];
}
delete [] next;
return i-j;
}
//KMP算法Next[]表构建
int * buildNext(char *p){
size_t m= strlen(p),j=0;
int * N=new int[m];//next表
int t=N[0]=-1;
while(j<m-1){
if(0>t||P[j]==P[t])//匹配
N[++j] = ++t;
else //失配
t=N[t]
}
}
//另一个版本
int KMP(char * t, char * p)
{
int i = 0;
int j = 0;
while (i < strlen(t) && j < strlen(p))
{
if (j == -1 || t[i] == p[j])
{
i++;
j++;
}
else
j = next[j];
}
if (j == strlen(p))
return i - j;
else
return -1;
}
void getNext(char * p, int * next)
{
next[0] = -1;
int i = 0, j = -1;
while (i < strlen(p))
{
if (j == -1 || p[i] == p[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}