https://www.lydsy.com/JudgeOnline/problem.php?id=4503
题意:
求第二个串在第一个中出现了几次,用通配符。求出每个串的起始位置。
分析:
bitset。
一共有26个字母,求出每个字母在第一个串中出现的位置。扫一遍第二个串,ans = p[[1]] & (p[T[2]]>>1) & (p[T[3]>>3]) & ... & p[T[n]>>n]。很好理解,就是每个字符所有出现的位置往右移,如果匹配,那么这一位and后,为1。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<cctype> #include<bitset> using namespace std; const int N = 200001; bitset<N> p[26], ans; char s[N], t[N]; int main() { scanf("%s", s); int l1 = strlen(s); scanf("%s", t); int l2 = strlen(t); for (int j=0; j<26; ++j) for (int i=0; i<l1; ++i) if (s[i] - 'a' == j) p[j].set(i); for (int i=0; i<=l1-l2; ++i) ans.set(i); for (int i=0; i<l2; ++i) { if (t[i] == '?') continue; ans &= (p[t[i] - 'a'] >> i); } cout << ans.count() << "\n"; for (int i=0; i<l1; ++i) if (ans[i]) printf("%d\n", i); return 0; }