hdu5716

地址:

题目:

带可选字符的多字符串匹配

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

Problem Description

有一个文本串,它的长度为m(1≤m≤2000000),现在想找出其中所有的符合特定模式的子串位置。

符合特定模式是指,该子串的长度为n(1≤n≤500),并且第i个字符需要在给定的字符集合Si中。

因此,描述这一特定模式,共需要S1,S2,...,Sn这n个字符集合。每个集合的大小都在1∼62之间,其中的字符只为数字或大小写字母。

Input

第一行为一个字符串,表示待匹配的文本串。注意文本串中可能含有数字和大小写字母之外的字符。

第二行为一个整数n。

以下n行,分别描述n个字符集合。每行开始是一个1∼62之间的整数,随后有一个空格,接下来有一个字符串表示对应字符集合的内容。整数表示字符集合的大小,因此它也就是字符串的长度。输入保证字符串中的字符只为数字或大小写字母且没有重复。<b>(注:本题有多组测试数据)</b>

Output

每当从某个位置开头的,长度为n的子串符合输入的模式,就输出一行,其中包含一个整数,为它在文本串的起始位置。位置编号从1开始。

如果文本串没有任何位置符合输入模式,则最后输出一个字符串"NULL",占一行。

Sample Input

aaaabacabcabd
3
3 abc
2 bc
3 abc

Sample Output

4
6
8
9

Source

2016"百度之星" - 复赛(Astar Round3)

思路:

  shiftand算法,不会的先百度吧。

  因为模式串比较长,所以bitset状压一下。

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 #define MP make_pair
 6 #define PB push_back
 7 typedef long long LL;
 8 typedef pair<int,int> PII;
 9 const double eps=1e-8;
10 const double pi=acos(-1.0);
11 const int K=1e6+7;
12 const int mod=1e9+7;
13
14 int getidx(char c)
15 {
16     if(‘0‘<=c&&c<=‘9‘)  return c-‘0‘;
17     if(‘a‘<=c&&c<=‘z‘)  return c-‘a‘+11;
18     if(‘A‘<=c&&c<=‘Z‘)  return c-‘A‘+37;
19     return 63;
20 }
21
22 char sa[2000007],sb[300];
23 bitset<500>bt[65],d;
24 int n;
25 int main(void)
26 {
27     //freopen("in.acm","r",stdin);
28     while(gets(sa))
29     {
30         memset(bt,0,sizeof bt);
31         scanf("%d",&n);
32         for(int i=0,len;i<n;i++)
33         {
34             scanf("%d%s",&len,sb);
35             for(int j=0;j<len;j++)  bt[getidx(sb[j])][i]=1;
36         }
37         int len=strlen(sa),ff=0;
38         d.reset();
39         for(int i=0;i<len;i++)
40         {
41             d <<=1;
42             d[0]=1;
43             d &= bt[getidx(sa[i])];
44             if(d[n-1])    printf("%d\n",i-n+2),ff=1;
45         }
46         getchar();
47         if(!ff) printf("NULL\n");
48     }
49     return 0;
50 }
时间: 2024-10-11 21:51:34

hdu5716的相关文章

HDU5716 : 带可选字符的多字符串匹配

shift-and算法,设$v[i][j]$表示文本串长度为$i$的前缀能否匹配模式串长度为$j$的前缀,$f[i][j]$表示字符$i$能否匹配模式串的第$j$个位置,那么有$v[i+1][j+1]=v[i][j]\ and\ f[s[i+1]][j+1]$. 显然$j$这一维可以用bitset加速,时间复杂度$O(\frac{nm}{64})$. #include<cstdio> #include<bitset> int n,i,j,flag;std::bitset<50