hdu5972(bitset)

Regular Number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1746    Accepted Submission(s): 488


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


题意:给一个长度为n的数字子串t,并给出每一位可能的数字,然后再给一个大串s,问s中有多少子串能匹配t。

思路:bitset。

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<bitset>
using namespace std;
bitset<1005>dat[11],ans;
char s[5000006];
int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        for(int i=0;i<11;i++)dat[i].reset();
        int a,x;
        /*记录每一个数字在那些位中出现*/
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a);
            for(int j=0;j<a;j++)
            {
                scanf("%d",&x);
                dat[x].set(i);
            }
        }
        ans.reset();
        scanf("%s",s);
        int len = strlen(s);
        for(int i=0;i<len;i++)
        {
            /*
            ans左移一位相当于匹配的再多一位,
            最后一位置1,观察它是否可能成为匹配子串的头
            
            当ans[n-1]=1时代表输入n位后每一位都匹配
            */
            ans<<=1;  
            ans[0]=1;  
            ans&=dat[s[i]-'0'];
            if(ans[n-1])
            {
                char c=s[i+1];
                s[i+1]='\0';
                printf("%s\n",s+i-n+1);
                s[i+1]=c;
            }
        }
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值