Shift-And 学习笔记

对于每种字符 (c in Sigma),构造掩码 (B_c),其中 (B_c[i]=[s[i]=c])。维护二进制串 (D),假设当前文本串扫描到了第 (i) 位,则 (D[j]=1) 当且仅当模式串的前缀 (p[1..j]) 与文本串前缀 (s[1..i]) 的长度为 (j) 的后缀完全相等。

每次读入一个新字符后,将 (D) 左移一位并加上 (1),与该位字符对应的掩码按位与,得到新的 (D)

如果存在某次操作后,使得 (D) 的最高位是 (1),根据定义,即此时文本串当前前缀的长度为 (|p|) 的后缀与 (p) 完全相同,则 (i) 是一个匹配成功的末尾位置。

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 10005;

bitset<N> b[N],d;
char s[N],p[N];
int ls,lp;

signed main()
{
    ios::sync_with_stdio(false);

    cin>>s+1>>p+1;
    ls=strlen(s+1);
    lp=strlen(p+1);

    for(int i=1;i<=lp;i++)
    {
        b[p[i]][i]=1;
    }

    for(int i=1;i<=ls;i++)
    {
        d<<=1;
        d[1]=1;
        d&=b[s[i]];
        if(d[lp]) cout<<i<<" ";
    }
}

原文地址:https://www.cnblogs.com/mollnn/p/13680669.html