• 【笔记】Shift-And算法&Shift-OR算法


    Shift-And

    S表示原串,T表示目标串,要在S中搜索T

    D是一个bitset:D[n-1,n-2,...,1,0]共n位

    x控制S串的扫描,当扫描到字符S[x]时,D的第y位D[y]=1当且仅当T[0..y]是S[0..x]的一个后缀

    B是一个map,key是题目字符集合,value是一个bitset,记录该字符在模式串T的哪些位置出现

    例如,字符c 在T[2] 处出现,那么B['c'] = 000100 (对于字符串,低位在左;对于B['c'],低位在右);同理,a 在T[0],T[3] 处出现,B['a'] = 001001.

    初始D[0]=1当且仅当S[i]=T[0]

    假设当前处理到S[x],需要对D进行更新,D[j]=1当且仅当D[j-1]==1&&S[i]=T[j]

    所以 D=(D<<1|1)&B[s[x]];

    Shift-OR

    用0表示一个数在集合里,1表示不在

    D=(D<<1)|B[s[x];B,D初始化全1

    #include<bits/stdc++.h>
    using namespace std;
    bitset<1001>B[10];
    bitset<1001>D;
    int n,m;
    void csh(){
        for(int i=0;i<10;i++) B[i].set();
        D.set();
    }
    char s[5000005];
    void output(int x){
        int be = x-n+1;
        char tmp = s[x+1];
        s[x+1]='';
        puts(s+be);
        s[x+1]=tmp;
    }
    void input(){
        int x;
        for(int i=0;i<n;i++){
        scanf("%d",&m);
        while(m--){
            scanf("%d",&x);
            B[x][i]=0;
        }
        }
        scanf("%s",s);
        m = strlen(s);
    }
    
    void solve(){
        for(int i=0;i<m;i++) {
        D=(D<<1)|B[s[i]-'0'];
        if(D[n-1]==0)output(i);
        }
    }
    int main(){
        while(scanf("%d",&n)!=EOF) {
        csh();
        input();
        solve();
        }
    }
  • 相关阅读:
    更改已经签名的app中的内容
    POJ 1611 The Suspects
    hibernate session缓存
    男儿当自强
    图遍历的演示
    nginx源代码分析--事件模块 &amp; 琐碎
    多线程在python中的使用 thread
    机房收费 &amp; 廊院食堂
    the steps that may be taken to solve a feature selection problem:特征选择的步骤
    早绑定和迟绑定技术的通俗分析
  • 原文地址:https://www.cnblogs.com/greenty1208/p/9709851.html
Copyright © 2020-2023  润新知