zoukankan      html  css  js  c++  java
  • 【笔记】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();
        }
    }
  • 相关阅读:
    设计模式 创建型 抽象工厂
    mysql 案例 ~ 分析执行完的大事务
    mysql 查询优化案例汇总
    mysql 原理 ~ innodb恢复机制
    mysql 原理~ 乐观锁和悲观锁
    mysql 原理 ~ 常规锁
    mysql 5.7 ~ 新特性
    mysql 原理 ~ checkpoint
    mysql原理~undo管理
    mysql原理~undo
  • 原文地址:https://www.cnblogs.com/greenty1208/p/9709851.html
Copyright © 2011-2022 走看看