转自:http://blog.csdn.net/likid1412/article/details/7908984
BF算法是一种简单模式匹配算法BF算法,时间复杂度为O(m*n)。
KMP算法是一种改进的字符串模式匹配算法,时间复杂度为O(m+n).。
下面只贴出了代码,详细的算法介绍可参考任一本算法书籍或者该网页:http://www.cppblog.com/oosky/archive/2006/07/06/9486.html(该网页我没看过,百度来的,建议还是看算法书好了)。
注:KMP的代码基本是自己写的,get_next()函数是改进过的。BF代码直接从书上摘录的。参考书籍:《数据结构(C语言版)》
- #include<iostream>
- using namespace std;
- void get_next(const char* t, int* next, int len);
- int index_KMP(const char* s,const char* t, int pos = 0);
- int index_BF(const char* s, const char* t, int pos = 0);
- int main()
- {
- const char* S = "dasdadsdsd";
- const char* T = "dasdasd";
- cout << "use BF:" << endl;
- int index = index_BF(S, T);
- if (index > -1)
- cout << T << " is a substring of " << S << " at index " << index + 1 << endl;
- else
- cout << T << " is not a substring of " << S << endl;
- cout << "use KMP:" << endl;
- index = index_KMP(S, T);
- if (index > -1)
- cout << T << " is a substring of " << S << " at index " << index + 1 << endl;
- else
- cout << T << " is not a substring of " << S << endl;
- return 0;
- }
- // O(m+n)
- int index_KMP(const char *S, const char *T, int pos)
- {
- // 求T在主串S中第pos个字符之后的位置的KMP算法。
- // 其中,T非空,1 <= pos <= strlen(S)。
- int s_len = strlen(S);
- int t_len = strlen(T);
- if(t_len > s_len)
- {
- return -1;
- }
- int *next = new int[t_len];
- get_next(T, next, t_len); // 获取模式串T的next值
- int count = 0;
- int i = pos, j = 0;
- while ((i < s_len) && (j < t_len))
- {
- if ((j == -1) || (S[i] == T[j]))
- {
- ++i;
- ++j;
- }
- else
- j = next[j];
- ++count;
- }
- delete[] next;
- next = NULL;
- cout << "\nKMP loop count: " << count << endl;
- if (j >= t_len)
- return i - j;
- else
- return -1;
- }
- void get_next(const char* t, int* next,int len)
- {
- // 求模式串T的next函数修正值并存入数组next。
- int j = 0; //求解每个next[j]
- next[0] = -1; //递推基本条件,然后求解next[j+1]
- int k = -1; //向后递推位置下标
- /*
- next[j]=k =>T0...Tk-1=Tj-k...Tj-1
- 求解next[j+1]
- 1> 如果T0..Tk-1Tk=Tj-k...Tj-1Tj=>next[j+1]=k+1=next[j]+1;
- 2>Tk<>Tj,next[k]=k', 如果Tj=Tk'=>next[j+1]=k'+1=next[k]+1=next[next[j]]+1;
- 3>依次递推 最后情况next[j+1]=next[0]+1=0,即
- */
- for (int condition = len - 1; j < condition;)
- {
- if ((k == -1) || (t[j] == t[k])) //k==-1证明已经与t[0]不匹配了,此时next[j+1]=0;
- {
- ++j;
- ++k;
- if (t[j] != t[k])
- next[j] = k;
- else
- next[j] = next[k];
- // 若Tj = Tk,则当主串中字符Si和Tj比较不等时,不需要再和Tk进行比较,
- // 而直接和TNext[k]进行比较,即此时的next[j]应和next[k]相同。
- //cout << "next[" << j << "]: " << next[j] << endl;
- }
- else
- k = next[k];
- }
- }
- // O(m*n)
- int index_BF(const char* S, const char* T, int pos)
- {
- // 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0
- // 其中,T非空,0 <= pos < strlen(S)
- int s_len = strlen(S), t_len = strlen(T);
- int i = pos, j = 0;
- int count = 0;
- while (i < s_len && j < t_len)
- {
- if (S[i] == T[j])
- {
- ++i;
- ++j;
- }
- else
- {
- i = i - j + 1;
- j = 0;
- }
- ++count;
- }
- cout << "\nBF loop count: " << count << endl;
- if (j == t_len)
- return i - j;
- else
- return -1;
- }