博客园的编辑器太难用了。。。。。。。。。。。
BF算法即暴力算法,很简单,随便举个栗子:
#include<iostream> #include<cstring> using namespace std; // S[]: 要匹配的链 // T[]: 模式串 int BFsearch(int start, char S[], char T[]) { int slen = strlen(S); int tlen = strlen(T); int i, j; for(i = 0; i < slen - tlen; i++) { for(j = 0; j < tlen; j++) if(S[i + j] != T[j]) break; if(j == tlen) cout << i + 1 << endl; } } int main() { char S[]="cababaabcacb"; char T[]="abcac"; BFsearch(0, S, T); return 0; }
KMP算法:
主要的实现内容包括一个getNext函数以及一个比较字符串和模式的函数;
其中getNext函数的实现最为关键。原理在其他很多文章中有介绍。这里说一下我自己觉得比较重要的地方。
int next[20]; char S[]="cababaabcacb"; char T[]="abcac"; void getNext(char T[]){ int k=-1; int j=0; next[j]=k; while(T[j]!='\0'){ if(k==-1||T[j]==T[k]){ k++; j++; next[j]=k; } else k=next[k]; } }
个人觉得其中最重要也最为精髓的地方在 k=next[k]; 这一句。
S[ ]为模式字符串
next[k]存储的是k 位置前缀与后缀相同的位数,
当出现T[j]!=T[k]时执行
k = next[k] 表示将K 赋值为当前位置之前的那一位(第K位)的前缀与
后缀相同位数目的next数组的第next[k]( 即P[next[k]] )
完整代码:
#include<iostream> #include <string.h> using namespace std; int next[20]; char S[]="cababaabcacb"; char T[]="abcac"; void getNext(char T[]){ int k=-1; int j=0; next[j]=k; while(T[j]!='\0'){ if(k==-1||T[j]==T[k]){ k++; j++; next[j]=k; } else k=next[k]; } } int KMPsearch(char S[],int start,char T[]){ int slen = strlen(S); int tlen = strlen(T); int i=start; int j=0; while(i<slen && j<tlen) { if(j==-1||S[i]==T[j]){ i++; j++; } else j=next[j]; } if(T[j]=='\0') return (i-j+1); else return 0; } int main(){ getNext(T); for(int k=0;T[k]!='\0';k++) cout<<next[k]<<" "; cout<<endl; cout<<KMPsearch(S,0,T); return 0; }