BZOJ3507.【CQOI2014】通配符匹配
2018-01-09 17:14
399 查看
Description
几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户。最常见的通配符有两个,一个是星号(“*”),可以匹配0个及以上的任意字符:另一个是问号(“?”),可以匹配恰好一个任意字符。
现在需要你编写一个程序,对于给定的文件名列表和一个包含通配符的字符串,判断哪些文件可以被匹配。
Input
第一行是一个由小写字母和上述通配符组成的字符串。第二行包含一个整数n,表示文件个数。
接下来n行,每行为一个仅包含小写字母字符串,表示文件名列表。
Output
输出n行,每行为“YES”或“NO”,表示对应文件能否被通配符匹配。Sample Input
*aca?ctc6
acaacatctc
acatctc
aacacatctc
aggggcaacacctc
aggggcaacatctc
aggggcaacctct
Sample Output
YESYES
YES
YES
YES
NO
HINT
对于1 00%的数据字符串长度不超过1 00000
1 <=n<=100
通配符个数不超过10
题解
题目有一个很重要的东西,就是通配符不超过10个。
先考虑一种很显然的方法,
设fi,j表示一个串匹配到i,另外一个串匹配到j,是否合法。
只要判断的时候将?当做所以字符,* 特殊处理一下就可以了。
但是这个时间复杂度是不可以接受的,
就对状态稍微改一下:
设fi,j表示一个串匹配到第i个通配符,匹配到j,是否合法。
就按照通配符就原串分为几个部分,然后逐一匹配。
用hash来判断两个字符串是否相等。
code
#pragma GCC optimize(2) #pragma G++ optimize(2) #include<queue> #include<cstdio> #include<iostream> #include<algorithm> #include <cstring> #include <string.h> #include <cmath> #include <math.h> #define ll long long #define ull unsigned long long #define N 100003 #define M 102 #define db double #define P putchar #define G getchar #define mo 13890604 #define zm 19260817 using namespace std; char ch; void read(int &n) { n=0; ch=G(); while((ch<'0' || ch>'9') && ch!='-')ch=G(); ll w=1; if(ch=='-')w=-1,ch=G(); while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G(); n*=w; } db max(db a,db b){return a>b?a:b;} db min(db a,db b){return a<b?a:b;} ll abs(ll x){return x<0?-x:x;} ll sqr(ll x){return x*x;} void write(ll x){if(x>9) write(x/10);P(x%10+'0');} char s ,t ; int len,n,pos[13],cnt; ull s1 ,s2 ,p ; bool f[13] ; ull get1(int x,int y) { return x>y?0:s1[y]-s1[x-1]*p[y-x+1]; } ull get2(int x,int y) { return x>y?0:s2[y]-s2[x-1]*p[y-x+1]; } int main() { p[0]=1; for(int i=1;i<N;i++) p[i]=p[i-1]*zm; scanf("%s",s+1); len=strlen(s+1); for(int i=1;i<=len;i++) { if(s[i]<'a' || s[i]>'z')pos[++cnt]=i; s1[i]=s1[i-1]*zm+s[i]; } s[pos[++cnt]=++len]='?'; read(n); while(n--) { scanf("%s",t+1); len=strlen(t+1); t[++len]='!'; for(int i=1;i<=len;i++) s2[i]=s2[i-1]*zm+t[i]; memset(f,0,sizeof(f)); f[0][0]=1; for(int i=0;i<cnt;i++) { if(s[pos[i]]=='*') { for(int j=1;j<=len;j++) if(f[i][j-1])f[i][j]=1; } for(int j=0;j<=len;j++) if(f[i][j] && get1(pos[i]+1,pos[i+1]-1)==get2(j+1,j+pos[i+1]-pos[i]-1)) { if(s[pos[i+1]]=='?')f[i+1][j+pos[i+1]-pos[i]]=1; else f[i+1][j+pos[i+1]-pos[i]-1]=1; } } if(f[cnt][len])P('Y'),P('E'),P('S'); else P('N'),P('O'); P('\n'); } }
相关文章推荐
- BZOJ3507 [Cqoi2014]通配符匹配 【哈希 + 贪心】
- BZOJ3507: [Cqoi2014]通配符匹配 解题报告
- BZOJ3507: [Cqoi2014]通配符匹配
- bzoj3507【CQOI2014】通配符匹配
- JZOJ 3600. 【CQOI2014】通配符匹配
- bzoj3507 [Cqoi2014]通配符匹配
- [CQOI2014][bzoj3507] 通配符匹配 [字符串hash+dp]
- 【bzoj3570】 Cqoi2014—通配符匹配
- 【CQOI2014】通配符匹配
- 字符串通配符匹配-2014华为机试题目
- JavaScript DOM 中利用通配符匹配元素
- P3165 [CQOI2014]排序机械臂
- BZOJ 3504: [Cqoi2014]危桥 [最大流]
- Redis 删除匹配通配符的key
- [Lintcode]Wildcard Matching 通配符匹配
- 161、腾讯现场招聘问题 通配符匹配
- BZOJ 3504 [Cqoi2014] 危桥 最大流
- 通配符的匹配很全面, 但无法找到元素 'tx:annotation-driven'
- 通配符(.*)等模糊匹配搜索
- BZOJ 3505: [Cqoi2014]数三角形 [组合计数]