1. 程式人生 > >hdu 5972---Regular Number(字串匹配)/// 還有一個Shift_and演算法

hdu 5972---Regular Number(字串匹配)/// 還有一個Shift_and演算法

Regular Number

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

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 ,representing that the i-th position of regular expression has numbers to be selected.Next there are 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位數,接下來有N行,第i行先輸入n,表示這個數的第i 位上可以在接下來的n個數中挑選,然後i 行再輸n個數。

然後輸入需要匹配的母串,讓你輸出母串中有多少個可行的N位子串。

解:

這題首先沒法使用KMP,因為在匹配失敗後沒法返回到準確的位置。

然後在網上向別人學了下程式碼,才明白這題bitset的巧妙的運用。

這題 bitset 的使用相當於是作為一個指標來使用的。

首先用bitset定義出現的數會在哪幾位上出現,置為1。

定義ans的初始位為1,每一次母串對應位與該位出現的數的bitset進行與比較(表明該位上是否能出現該數)。因為一旦失敗則置0,因此如果1出現在ans的第n位上則表明之前的n-1位全部匹配成功。

此題,使用bitset的複雜度為O(n*len/x)(len為母串長,x為機器碼長)。

此題必須使用puts,gets進行輸入輸出,不然會超時。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <bitset>
using namespace std;
const int maxn=1e6+50;
char str[5*maxn];
bitset<1005> s[20];
bitset<1005> ans;
 
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<20;i++)
        s[i].reset();
        ans.reset();
        for(int i=0;i<n;i++)
        {
            int N,temp;
            scanf("%d",&N);
            for(int j=0;j<N;j++)
            {
                scanf("%d",&temp);
                s[temp].set(i);
            }
        }
        getchar();
        gets(str);
        int len=strlen(str);
        for(int i=0;i<len;i++)
        {
            ans=ans<<1;
            ans[0]=1;
            ans&=s[str[i]-'0'];
            if(ans[n-1]==1)
            {
                char temp=str[i+1];
                str[i+1]='\0';
                puts(str+i-n+1);
                str[i+1]=temp;
            }
        }
    }
    return 0;
}
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<memory>
#include<list>
#include<bitset>
#include<string>
#include<functional>

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int MAXN = 5e6 + 9;
#define L 1009
#define INF 1000000009
#define eps 0.00000001
#define MOD 1000
bitset<1009> B[256], D;
char str[MAXN];
int main()
{
    int n, tmp, t;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &tmp);
        while (tmp--)
        {
            scanf("%d", &t);
            B[t].set(i);
        }
    }
    getchar();
    gets(str);
    int l = strlen(str);
    for (int i = 0; i < l; i++)
    {
        D = (D << 1).set(0)&B[str[i] - '0'];
        if (D[n - 1])
        {
            char ch = str[i + 1];
            str[i + 1] = '\0';
            puts(str + i - n + 1);
            str[i + 1] = ch;
        }
    }
}