模式匹配
1、目标
查找模式子串,匹配确认。匹配算法可使用BF算法也可使用KMP算法。
KMP算法牛逼!
KMP算法可大大提高程序效率;BF算法又称暴力循环算法,简单易懂但效率低下。
例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_S 100
void nextnum(char T[],int next[],int T_len);
void display(int next[],int length);
int main()
{
printf("String S: ");
char S[MAX_S];//目标字符串
scanf("%s",S);
int S_len=strlen(S)-1;
printf("S length: %d \n",S_len+1);
printf("String T: ");
char T[20]="ababc";//模式字符串
scanf("%s",T);
int T_len=strlen(T)-1;//strlen()不包括结束符null,所以strlen(T)是字符串的真正长度
printf("T length: %d \n",T_len+1);
int next[20];//next[j]
nextnum(T,next,T_len);//获取next数值
display(next,T_len);
printf("next[j] ok \n");
//匹配部分,当不匹配时会根据next值进行跳转
int stepS=0,stepT=0;//stepS是主串的匹配到的位置,stepT是模式子串匹配到的位置
while (stepT<=T_len&&stepS<=S_len)
{
if(S[stepS]==T[stepT]) {
stepS++;
stepT++;
}
else {
stepT=next[stepT];
if (stepT<0) {
stepT++;
stepS++;
}
}
}
if(stepT>T_len) printf("perfect \n");
else printf("not match \n");
}
//求next值
void nextnum(char T[],int next[],int T_len)
{
int k=0;
int j=1;
int i=0;
if(T_len>1){
next[0]=-1;//
next[1]=0;
while(j<T_len){//因为数组的起始位置是T[0],所以T[sizeof(T)-2]是最后一个字符,而且算法要求j前面k-1 不包括j
if (T[j]==T[i]){
k++;
j++;
i++;
}
else{
if(T[j]==T[0]){
k=1;
i++;
}
else{
k=0;
i=0;
}
j++;
}
next[j]=k;
}
}
else if(T_len==1){
next[0]=-1;
next[1]=0;
}
else{
next[0]=-1;
}
return;
}
void display(int next[],int length)
{
int nextlen=length;
for (int i=0;i<=nextlen;i++){
printf("%d ",next[i]);
}
}
理解BF算法,关键在于理解next跳转机制。