HDU-5972 Regular Number (Shift-And字符串匹配)
题意
模式串第 \(i\) 个位置可以有 \(a_i\) 个字符满足要求,给出这 \(a_i\) 个字符。给出一个主串,输出主串中所有能与模式串匹配的子串。
思路
Shift-And 算法:学习传送门
Shift-And 算法基本上也只适用这种给出模式串字母表的情况,因模式串有太多种可能而不能用 kmp 算法,这道题就是根据 Shift-And 的解法特性来出的。时间复杂度 \(O(nm/x)\) ,\(n\) 为主串长度,\(m\) 为模式串长度,\(x\) 为计算机的位数。
代码实现
#include <cstdio>
#include <bitset>
using std::bitset;
bitset<1010> b[11], D; // b[i][j]=1表示i这个值可以放在模式串的第j个位置
char s[5000010];
int main() {
int n;
while (~scanf("%d", &n)) {
for (int i = 0; i < 11; i++) b[i].reset();
D.reset();
for (int i = 0, nn, x; i < n; i++) {
scanf("%d", &nn);
while (nn--) {
scanf("%d", &x);
b[x].set(i);
}
}
getchar();
fgets(s, 5000005, stdin);
for (int i = 0; s[i]; i++) {
D <<= 1;
D.set(0);
D &= b[s[i]-'0'];
if (D[n-1]) {
char tmp = s[i+1];
s[i+1] = '\0';
puts(s + i-n+1);
s[i+1] = tmp;
}
}
}
return 0;
}
作者:_kangkang
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。