zoukankan      html  css  js  c++  java
  • 51nod 1532 带可选字符的多字符串匹配(位运算)

    题意:

    有一个文本串,它的长度为m (1 <= m <= 2000000),现在想找出其中所有的符合特定模式的子串位置。
    符合特定模式是指,该子串的长度为n (1 <= n <= 500),并且第i个字符需要在给定的字符集合Si中。
    因此,描述这一特定模式,共需要S1,S2,...,Sn这n个字符集合。每个集合的大小都在1~62之间,其中的字符只为数字或大小写字母。

    题解:

    很类似之前做过的一道cf的题目,利用shift-and算法优化到nm/64的复杂度

    每一次匹配的结果实际上就是(v<<1)&Mask[S[i]]的结果(有点像卷积)

    然后一步步左移就可以了。

    还有一个比较坑的地方是会卡cin(有些奇怪的字符)

    需要用gets和getchar来做。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <bitset>
    using namespace std;
    const int maxn = 2000050;
    typedef long long LL;
    int tab[250];
    char S[maxn], T[505];
    bitset<505> v, Mask[64];
    int L, n, x;
    void pre(){
        memset(tab, 1, sizeof(tab));
        int tot = 0;
        for(int i = 'a'; i <= 'z'; i++) tab[i] = tot++;
        for(int i = 'A'; i <= 'Z'; i++) tab[i] = tot++;
        for(int i = '0'; i <= '9'; i++) tab[i] = tot++;
    }
    int main()
    {
        pre();
        while(gets(S)){
            L = strlen(S);
            cin>>n;
            for(int i = 0; i <= 62; i++) Mask[i].reset(); v.reset();
            for(int i = 1; i <= n; i++){
                scanf("%d", &x);
                cin>>T;
                for(int j = 0; j < x; j++) Mask[tab[T[j]]][i] = 1;
            }
            int fail = 1;
            v[0] = 1;
            for(int i = 0; i < L; i++){
                if(S[i] < 200 && tab[S[i]] < 70) v = (v<<1)&Mask[tab[S[i]]]; else v.reset();
                v[0] = 1;
                if(v[n] == 1){
                    fail = 0;
                    printf("%d
    ", i-n+2);
                }
            }
            if(fail) printf("NULL
    ");
            getchar();
        }
        return 0;
    }
  • 相关阅读:
    管理员必备的Linux系统监控工具
    kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
    RedHat linux配置yum本地资源
    RedHat Linux RHEL6配置本地YUM源
    c语言中的fgets函数
    sprintf()函数的用法
    spring boot整合JWT例子
    spring boot 自定义过滤器链
    (转)ArrayList和LinkedList的几种循环遍历方式及性能对比分析
    (转)Springboot 中filter 注入对象
  • 原文地址:https://www.cnblogs.com/Saurus/p/7648021.html
Copyright © 2011-2022 走看看