zoukankan      html  css  js  c++  java
  • shift-and 算法初体验

    shift-and算法的思想与kmp的算法思想类似,更简单

    shift-and算法的适用范围是字符串匹配,但是此时模板串可以有很多个

    直接拿模板题:hdu 5972 来说

    题意:模式串有n位长度,n的大小是1000,每一位有x种选择,x的大小是10,也就是说模式串组合的话,大约可以组合出来10^1000种,于是普通的AC自动机什么的都GG了

    shift-and是用bitset实现的,bitset是高端卡常题的宠儿,很少被我使用的经典STL

    bitset可以想象成是vector容器,对于每一位只占用一个字节,也就是char型的八分之一的大小,于是省时又省空间

    需要注意的是:假设声明bitset<int>foo;  那么foo[0]会显示在最右端,foo[n-1]会显示在最左端,刚好与普通的数组是相反的

    foo.set()  全部设置为1

    foo.reset()   全部设置为0

    foo.set(x)    将foo[x]设置成1

    foo.reset(x)  将foo[x]设置成0

    按照代码理解吧~

    首先是输入部分

    
    

    build() 函数的作用是构建bitset ,  solve() 函数就是解决问题 具体怎么实习的后面介绍

    首先我声明的bitset长度就是n的大小,10个bitset,记录的就是每一个数字可以出现在第几位

    接下来ans也是一个bitset,他记录我们在处理过程中的结果

    每一步 我们就将当前位直接置1,询问这一位是否可以匹配,与前面的,当前面也可以,这一步也可以的话,那么这一个就匹配成功

    代码如下:

        #include<stdio.h>
        #include<iostream>
        #include<algorithm>
        #include<string.h>
        #include<vector>
        #include<bitset>
    
        using namespace std;
    
        const int maxn = 1003;
    
        int n , x , num;
        vector<int>V[maxn];
        char s[5000006];
        bitset<maxn>b[13] , ans;
    
        void build()
        {
            for(int i=0; i<10; i++)
            {
                b[i].reset();
            }
            ans.reset();
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<V[i].size(); j++)
                {
                    b[V[i][j]].set(i);
                }
            }
        //    for(int i=0; i<10; i++)
        //    {
        //        cout<<b[i]<<endl;
        //    }
        }
    
        void solve()
        {
            int len = strlen(s);
            for(int i=0; i<len; i++)
            {
                int tmp = s[i]-'0';
                ans = ans<<1;
                ans.set(0);
                ans = ans&b[tmp];
                if(ans[n-1]==1)
                {
                      char ttmp = s[i+1];
                      s[i+1] = '';
                      puts(s+i+1-n);
                      s[i+1] = ttmp;
                }
            }
        }
    
        void init()
        {
            for(int i=0; i<n; i++)
            {
                V[i].clear();
            }
        }
    
        int main()
        {
            while( scanf("%d" , &n) != EOF )
            {
                init();
                for(int i=0; i<n; i++)
                {
                    scanf("%d" , &x);
                    for(int j=1; j<=x; j++)
                    {
                        scanf("%d" , &num);
                        V[i].push_back(num);
                    }
                }
                scanf("%s" , s);
                build();
                solve();
            }
    
    
            return 0;
        }
  • 相关阅读:
    洛谷 P3355 骑士共存问题
    Redis 安装
    Java 集合:(十八) Map接口
    并发编程——Java版【目录】
    Java 集合:(十七) Queue 常用接口:BlockingQueue 子接口
    Java 集合:(十六) Queue 常用接口:Deque 子接口
    Java 集合:(十五) Queue 子接口
    Java 集合:(番外篇一) ArrayList线程不安全性
    第十三章:StringTable
    Java 集合:(十三) Set实现类:LinkedHashSet
  • 原文地址:https://www.cnblogs.com/Flower-Z/p/9772534.html
Copyright © 2011-2022 走看看