Rabin_Karp(hash) HDOJ 1711 Number Sequence

 

题目传送门

 1 /*
 2   Rabin_Karp:虽说用KMP更好,但是RK算法好理解。简单说一下RK算法的原理:首先把模式串的哈希值算出来,
 3         在文本串里不断更新模式串的长度的哈希值,若相等,则找到了,否则整个模式串的长度的哈希值向右移动一位
 4 */
 5 /************************************************
 6 * Author        :Running_Time
 7 * Created Time  :2015-8-5 14:04:26
 8 * File Name     :HDOJ_1711.cpp
 9  ************************************************/
10 
11 #include <cstdio>
12 #include <algorithm>
13 #include <iostream>
14 #include <sstream>
15 #include <cstring>
16 #include <cmath>
17 #include <string>
18 #include <vector>
19 #include <queue>
20 #include <deque>
21 #include <stack>
22 #include <list>
23 #include <map>
24 #include <set>
25 #include <bitset>
26 #include <cstdlib>
27 #include <ctime>
28 using namespace std;
29 
30 #define lson l, mid, rt << 1
31 #define rson mid + 1, r, rt << 1 | 1
32 typedef unsigned long long ull;
33 typedef long long ll;
34 const int MAXN = 1e6 + 10;
35 const int MAXM = 1e4 + 10;
36 const int INF = 0x3f3f3f3f;
37 const ull KEY = 100000007;
38 int a[MAXN], b[MAXM];
39 int n, m;
40 
41 int match(void) {
42     ull h = 1;
43     for (int i=0; i<m; ++i)    h *= KEY;
44     ull ah = 0, bh = 0;
45     for (int i=0; i<m; ++i)    ah = ah * KEY + a[i];
46     for (int i=0; i<m; ++i)    bh = bh * KEY + b[i];
47     for (int i=0; i+m<=n; ++i)    {
48         if (ah == bh)   return i + 1;
49         if (i + m < n) {
50             ah = ah * KEY + a[i+m] - a[i] * h;
51         }
52     }
53     return -1;
54 }
55 
56 int main(void)    {     //HDOJ 1711 Number Sequence
57     int T;  scanf ("%d", &T);
58     while (T--) {
59         scanf ("%d%d", &n, &m);
60         for (int i=0; i<n; ++i)    scanf ("%d", &a[i]);
61         for (int i=0; i<m; ++i)    scanf ("%d", &b[i]);
62         printf ("%d\n", match ());
63     }
64 
65     return 0;
66 }
 1 /*
 2     题目链接:http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4194
 3     给你两个字符串A,B,请输出B字符串在A字符串中出现了几次。
 4 */
 5 /************************************************
 6  * Author        :Running_Time
 7  * Created Time  :2015-8-5 14:04:26
 8  * File Name     :ZSTU 4194 字符串匹配
 9  ************************************************/
10 
11 #include <cstdio>
12 #include <algorithm>
13 #include <iostream>
14 #include <sstream>
15 #include <cstring>
16 #include <cmath>
17 #include <string>
18 #include <vector>
19 #include <queue>
20 #include <deque>
21 #include <stack>
22 #include <list>
23 #include <map>
24 #include <set>
25 #include <bitset>
26 #include <cstdlib>
27 #include <ctime>
28 using namespace std;
29 
30 #define lson l, mid, rt << 1
31 #define rson mid + 1, r, rt << 1 | 1
32 typedef unsigned long long ull;
33 typedef long long ll;
34 const int MAXN = 1e6 + 10;
35 const int INF = 0x3f3f3f3f;
36 const ull KEY = 100000007;
37 char t[MAXN], p[MAXN];
38 
39 int Rabin_Karp(void) {
40     int lent = strlen (t);
41     int lenp = strlen (p);
42     ull h = 1;
43     for (int i=0; i<lenp; ++i)    h *= KEY;
44     ull th = 0, ph = 0; int ret = 0;
45     for (int i=0; i<lenp; ++i)    th = th * KEY + t[i];
46     for (int i=0; i<lenp; ++i)    ph = ph * KEY + p[i];
47     for (int i=0; i+lenp<=lent; ++i)    {
48         if (th == ph)   {
49             ret++;
50             for (int j=i; j<=i+lenp-1; ++j) {       //找到了一个模式串,不能再用,整个跳过去
51                 th = th * KEY + t[j+lenp] - t[j] * h;
52             }
53             i += lenp - 1;  continue;
54         }
55         if (i + lenp < lent) {
56             th = th * KEY + t[i+lenp] - t[i] * h;
57         }
58     }
59     return ret;
60 }
61 
62 int main(void)    {     //ZSTU 4194 字符串匹配
63     while (scanf ("%s %s", t, p) == 2)  {
64         printf ("%d\n", Rabin_Karp ());
65     }
66 
67     return 0;
68 }
Rabin_Karp应用
 1 /*
 2     这就是赤裸裸的模板题,只不过用数字而已
 3 */
 4 /************************************************
 5 * Author        :Running_Time
 6 * Created Time  :2015-8-9 19:45:40
 7 * File Name     :KMP.cpp
 8  ************************************************/
 9 
10 #include <cstdio>
11 #include <algorithm>
12 #include <iostream>
13 #include <sstream>
14 #include <cstring>
15 #include <cmath>
16 #include <string>
17 #include <vector>
18 #include <queue>
19 #include <deque>
20 #include <stack>
21 #include <list>
22 #include <map>
23 #include <set>
24 #include <bitset>
25 #include <cstdlib>
26 #include <ctime>
27 using namespace std;
28 
29 #define lson l, mid, rt << 1
30 #define rson mid + 1, r, rt << 1 | 1
31 typedef long long ll;
32 const int MAXN = 1e6 + 10;
33 const int INF = 0x3f3f3f3f;
34 const int MOD = 1e9 + 7;
35 int nex[MAXN];
36 int s[MAXN], t[MAXN];
37 
38 void get_nex(int lm)    {
39     int i = 0, j = -1;   nex[0] = -1;
40     while (i < lm)  {
41         if (j == -1 || t[j] == t[i]) {
42             i++;    j++;    nex[i] = j;
43         }
44         else    j = nex[j];
45     }
46 }
47 
48 int KMP(int ln, int lm)   {
49     get_nex (lm);
50     int i = 0, j = 0;
51     while (i < ln)  {
52         while (j != -1 && s[i] != t[j]) j = nex[j];
53         i++;    j++;
54         if (j == lm) return (i - j + 1);
55     }
56     return -1;
57 }
58 
59 int main(void)    {     //HDOJ 1711 Number Sequence
60     int T;  scanf ("%d", &T);
61     while (T--)   {
62         int ln, lm; scanf ("%d%d", &ln, &lm);
63         for (int i=0; i<ln; ++i)   scanf ("%d", &s[i]);
64         for (int i=0; i<lm; ++i)   scanf ("%d", &t[i]);
65         printf ("%d\n", KMP (ln, lm));
66     }
67 
68     return 0;
69 }
KMP

 

posted @ 2015-08-05 16:35  Running_Time  阅读(214)  评论(0编辑  收藏  举报