题目来自:http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2315188.html
KMP算法开始是判断字符串b是否是字符串a的子串,朴素的算法是枚举,时间复杂度O(m*n)
然后KMP(三个人名字的缩写)发明了KMP算法使时间复杂度降到了O(m+n)
但是<string.h>里面明明有一个函数是strstr(a,b)判断b是否为a的子串啊啊啊啊!!!
这个写得蛮好:http://blog.chinaunix.net/uid-27164517-id-3280128.html
以下仅限于个人理解:
a和b字符串匹配过程中,在j位置开始不匹配了
在0-j中寻找b0 b1 b2 ... bk = b(j-1-k) ... b(j-1)
当b与a字符串失配b应当从k+1个字符开始与a中刚刚失配的位置进行匹配
所以要确定k的值,而k的取值仅与j的位置有关,所以用next[]数组来盛放相应位置k的值
next(j) = -1 起始位置
k+1 0 <= k < j-1 失配时b应当重新开始匹配的位置
0 其他
next[]数组的确立
void getNext(){ int k = -1; next[0] = -1; int j = 0; int len = strlen(str); while(j < len){ if(k == -1 || str[j] == str[k]){ k++; j++; next[j] = k; } else{ k = next[k]; } } }
http://poj.org/problem?id=3461
给a串和b串,求出b串中包含多少个a串
主要思路:
先对b进行next求解,然后对匹配到达最后进行计数……
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <cstdlib> #include <stack> #include <cctype> #include <string> #include <queue> #include <map> #include <set> using namespace std; const int INF = 0xffffff; const double ESP = 10e-8; const double Pi = 4 * atan(1.0); const int MAXN = 1000000 + 10; const long long MOD = 1000000007; const int dr[] = {1,0,-1,0,-1,1,-1,1}; const int dc[] = {0,1,0,-1,1,-1,-1,1}; typedef long long LL; LL gac(LL a,LL b){ return b?gac(b,a%b):a; } char str[10000+10]; char str1[MAXN]; int next[10000+10]; void getNext(){ int k = -1; int j = 0; next[0] = -1; int len = strlen(str); while(j < len){ if(k == -1 || str[j] == str[k]){ j++; k++; next[j] = k; } else{ k = next[k]; } } } int main() { #ifndef ONLINE_JUDGE freopen("inpt.txt","r",stdin); // freopen("output.txt","w",stdout); #endif int t; scanf("%d",&t); while(t--){ scanf("%s%s",str,str1); getNext(); int cnt = 0; int len = strlen(str); int len1 = strlen(str1); int j = 0; int i = 0; while(i < len1){ if(j == -1 || str[j] == str1[i]){ i++; j++; } else{ j = next[j]; } if(j == len){ cnt++; } } printf("%d\n",cnt); } return 0; }