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 }

 

posted @ 2014-12-12 21:47  Naturain  阅读(156)  评论(0编辑  收藏  举报