• hdu 5972---Regular Number(字符串匹配)


    题目链接

    Problem Description
    Using regular expression to define a numeric string is a very common thing. Generally, use the shape as follows:
    (0|9|7) (5|6) (2) (4|5)
    Above regular expression matches 4 digits:The first is one of 0,9 and 7. The second is one of 5 and 6. The third is 2. And the fourth is one of 4 and 5. The above regular expression can be successfully matched to 0525, but it cannot be matched to 9634.
    Now,giving you a regular expression like the above formula,and a long string of numbers,please find out all the substrings of this long string that can be matched to the regular expression.
     
    Input
    It contains a set of test data.The first line is a positive integer N (1 ≤ N ≤ 1000),on behalf of the regular representation of the N bit string.In the next N lines,the first integer of the i-th line is ai(1ai10),representing that the i-th position of regular expression has ai numbers to be selected.Next there are ai numeric characters. In the last line,there is a numeric string.The length of the string is not more than 5 * 10^6.
     
    Output
    Output all substrings that can be matched by the regular expression. Each substring occupies one line
     
    Sample Input
    4
    3 0 9 7
    2 5 7
    2 2 5
    2 4 5
    09755420524
     
    Sample Output
    9755
    7554
    0524
     
    Source
     
    题意:输入N ,表示有一个长为N的子串,接下来N行,每行输入ai 和ai个数,表示有ai个数,表示子串第i个字符为ai个数中的一个,也就是这个子串的正则式,然后输入一个主串,要求输出这个主串中包含的所有的子串。
     
    思路:使用bitset<N> b[10] ,b[i][j]表示值为i的数可以出现在子串的那些位置,即下标,那么对主串进行遍历 i=0:len-1 。另外定义一个变量bitset<N> ans ,每次先将ans左移一位,然后将最低位置1,然后令k=当前输入的数,将ans=ans&b[k], 如果当前ans[N-1]==1,那么主串s[i-N+1]~s[i]就是合法子串,输出;
     
    代码如下:
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <bitset>
    using namespace std;
    typedef long long LL;
    const int M=5*1e6+5;
    bitset<1005>b[12];
    bitset<1005>ans;
    char s[5000005];
    
    int main()
    {
        int N;
        while(scanf("%d",&N)!=EOF)
        {
            for(int i=0;i<10;i++) b[i].reset();
            for(int i=0;i<N;i++)
            {
                int n;
                scanf("%d",&n);
                for(int j=1;j<=n;j++)
                {
                    int k;
                    scanf("%d",&k);
                    b[k].set(i);
                }
            }
            getchar();
            gets(s);
            ans.reset();
            int len=strlen(s);
            for(int i=0;i<len;i++)
            {
                ans=ans<<1;
                ans.set(0);
                ans=ans&b[s[i]-'0'];
                if(ans[N-1]==1){
                   char c=s[i+1];
                   s[i+1]='';
                   puts(s+i-N+1);
                   s[i+1]=c;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    最小生成树Prim算法和Kruskal算法(转)
    tarjan有向图的强连通
    匈牙利算法
    字符类数组的常用函数
    三层登录——C#版
    监考风波
    SQL Server 2012 安装——安装 OR 卸载
    SQL Server 2012安装——.net framework 3.5离线安装
    坚定自我 守住寂寞
    浅谈三层
  • 原文地址:https://www.cnblogs.com/chen9510/p/6941626.html
Copyright © 2020-2023  润新知