Files
python/TangDou/AcWing/Statemachine/HDU-1711-Rabin-Karp.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

42 lines
1.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Rabin_Karp:虽说用KMP更好,但是RK算法好理解。简单说一下RK算法的原理:首先把模式串的哈希值算出来,
在文本串里不断更新模式串的长度的哈希值,若相等,则找到了,否则整个模式串的长度的哈希值向右移动一位
*/
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int N = 1e4 + 10;
const int M = 1e6 + 10;
const ULL KEY = 100000007;
int s[M], p[N];
int n, m;
int match() {
ULL h = 1;
for (int i = 0; i < n; i++) h *= KEY;
//对齐0~n-1
ULL ah = 0, bh = 0;
for (int i = 0; i < n; i++) ah = ah * KEY + s[i]; //模拟成KEY进制,然后利用ULL溢出的形式,相当于对2^64取模
for (int i = 0; i < n; i++) bh = bh * KEY + p[i];
//开始尝试匹配
for (int i = 0; i <= m - n; i++) {
if (ah == bh) return i + 1; //如果HASH值一致,则返回匹配位置,因本题要求数组下村从1开始,所以+1后返回
if (i < m - n) ah = ah * KEY + s[i + n] - s[i] * h; //怕越界,因为数据弱,不写if也能AC,但如果模式串最后一位是0,就狒狒了,原因看EXCEL
}
return -1;
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &m, &n);
for (int i = 0; i < m; i++) scanf("%d", &s[i]); //源串
for (int i = 0; i < n; i++) scanf("%d", &p[i]); //模式串
printf("%d\n", match());
}
return 0;
}