Poj--3461(字符串hash / KMP)
2014-12-12 21:43:40
思路:两种方法:字符串hash 和 KMP。
第一种:
根据巫大叔书里的方法写的。
把W看成一串B进制数,B取unsigned long long 100000007,先求出W串的hash值,再逐步求出T中每|W|长的串的hash,进行比对,符合就令答案+1。
H[k+1] = H[k] * B - s[k] * B^|W| + s[k+|W|],s[i]表示T中第i个字符,该公式表示从k开始长为|W|的子串的hash值转移到从k+1开始长为|W|的字串的hash值的方法。
1 /************************************************************************* 2 > File Name: 3461.cpp 3 > Author: Natureal 4 > Mail: 564374850@qq.com 5 > Created Time: Fri 12 Dec 2014 09:27:22 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 typedef unsigned long long ull; 26 const int INF = 1 << 30; 27 const ull B = 100000007; 28 29 int N; 30 char W[10010]; 31 char T[1000010]; 32 33 int main(){ 34 scanf("%d",&N); 35 while(N--){ 36 scanf("%s%s",W,T); 37 int len1 = strlen(W); 38 int len2 = strlen(T); 39 ull wh = 0,th = 0,base = 1; 40 for(int i = 0; i < len1; ++i){ 41 wh = wh * B + W[i]; 42 th = th * B + T[i]; 43 } 44 for(int i = 0; i < len1; ++i) base *= B; 45 int ans = 0; 46 for(int i = 0; i + len1 - 1 < len2; ++i){ 47 if(wh == th) ans++; 48 if(i + len1 < len2) th = th * B + T[i + len1] - T[i] * base; 49 } 50 printf("%d\n",ans); 51 } 52 return 0; 53 }
第二种:
直接上KMP
1 /************************************************************************* 2 > File Name: 3461.cpp 3 > Author: Natureal 4 > Mail: 564374850@qq.com 5 > Created Time: Sat 13 Dec 2014 12:23:14 AM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 typedef unsigned long long ull; 26 const int INF = 1 << 30; 27 28 int N,len1,len2; 29 char W[10010]; 30 char T[1000010]; 31 int P[10010]; 32 int ans; 33 34 void Get_P(){ 35 P[0] = -1; 36 int j = -1; 37 for(int i = 1; i < len1; ++i){ 38 while(j > -1 && W[j + 1] != W[i]) j = P[j]; 39 if(W[j + 1] == W[i]) j++; 40 P[i] = j; 41 } 42 } 43 44 void KMP(){ 45 int j = -1; 46 for(int i = 0; i < len2; ++i){ 47 while(j > -1 && W[j + 1] != T[i]) j = P[j]; 48 if(W[j + 1] == T[i]) j++; 49 if(j == len1 - 1) ans++; 50 } 51 } 52 53 int main(){ 54 scanf("%d",&N); 55 while(N--){ 56 scanf("%s%s",W,T); 57 len1 = strlen(W); 58 len2 = strlen(T); 59 Get_P(); 60 ans = 0; 61 KMP(); 62 printf("%d\n",ans); 63 } 64 return 0; 65 }