字符串匹配:暴力,KMP,horsepool实现(1)

来源:互联网 发布:安卓看美剧用什么软件 编辑:程序博客网 时间:2024/06/05 13:54
字符串匹配:暴力,KMP,horsepool实现(1)
#include /*结尾字符*/#define NVL '*' /*字符串匹配算法*tips:都是用最坏情况,描述时间渐进复杂度*//*暴力搜索 O(n) = O(n^2)*/int BF(char* W,char* T){int i,j;for(i=0,j=0;W[i]!=NVL;){if(T[j]==NVL) return i-j;if(T[j] == W[i]){j++;i++;}else if(j==0){ i++;}else{j=0;}}return -1;}/*KMP算法*在模式串T[0],T[1]...T[n]中可能存在T[0]...T[k-1] == T[j-k+1]...T[j] k个首尾相同的子串。*则当模式串T[j+1]与待匹配字串W[i+1]不匹配时,存在T[0]...T[k-1]==T[j-k+1]...T[j]==W[i-k+1]...W[i]的关系*则可以直接拿T[(k-1)+1]与W[i+1]相比,而不是拿T[0]与W[i+1]相比*设计:*假设与T[]同长数组NEXT[]指示满足上述关系的下标 k-1。*1.W长度>=2.*2.NEXT[0]=-1 指示向右挪一位*                       *3.NEXT[i]=NEXT[i-1] + W[NEXT[i-1]+1]==W[i]?1:0;**/void GetNext(char* W,int *next){    int i,j;    for(i=0;W[i]!=NVL;i++){        if(i==0) {*(next) = -1;}        else if(i==1) {*(next+1) = W[0]==W[1]?0:-1;}        else {            j = next[i-1];            if(W[j+1]==W[i]){                next[i]=j+1;            }            else{                next[i]=-1;            }        }    }}/*KMP的算法好坏取决于,模式串中Next[]数组指向最大的重复字符串*关键在于:Next[]如何指向最大的下标?*O(n) = O(MN)*/int KMP(char* W,char*T){    int next[255]={0};    int i,j;    GetNext(T,next);    for(i=0,j=0;W[i]!=NVL;){        if(T[j]==NVL) return i-j;        if(W[i]==T[j]){i++;j++;}        else{            if(j==0){ i++;j=0;}            else j=next[j-1]+1;        }    }    return -1;}/*Horsepool创新从右向左比较,尽可能的使模式字符串向后跑 比KMP要好理解 且节省空间*/int Horsepool(char* W,char* T){    int i,j,k1,k2;    for(i=0;T[i]!=NVL;i++);    i=j=i-1; //第一次ij的比较位置,默认T长度是小于等于W的长度    for(;W[i]!=NVL;){    k1=k2=0;    while(k2<=j&&k1<=i&&W[i-k1]==T[j-k2]){ k1++;k2++;} //找到不匹配位置 A    if(k1>j) return i-k1+1;//找到    while(k2<=j&&W[i-k1]!=T[j-k2]) k2++;//找到与A位置匹配的左边字符的位置B    i+=k2-k1; //A B对其,进行下一次匹配    }    return -1;}int main(void) {// your code goes herechar W[100]={'\0'},T[100]={'\0'};int next[255]={};int i; scanf("%s %s",W,T);//  printf("%d\n",BF(W,T));//  printf("%d\n",KMP(W,T));printf("%d\n",Horsepool(W,T));return 0;}
原创粉丝点击