Description

几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户。最常见的通配符有两个,一个是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可以匹配恰好一个任意字符。

现在需要你编写一个程序,对于给定的文件名列表和一个包含通配符的字符串,判断哪些文件可以被匹配。

Input

第一行是一个由小写字母和上述通配符组成的字符串。

第二行包含一个整数n,表示文件个数。

接下来n行,每行为一个仅包含小写字母字符串,表示文件名列表。

Output

输出n行,每行为“YES”或“NO”,表示对应文件能否被通配符匹配。

Sample Input

*aca?ctc

6

acaacatctc

acatctc

aacacatctc

aggggcaacacctc

aggggcaacatctc

aggggcaacctct

Sample Output

YES

YES

YES

YES

YES

NO

HINT

对于1 00%的数据

字符串长度不超过100000

1 <=n<=100

通配符个数不超过10


本题有弱化版[AHOI2005]VIRUS 病毒检测题解

关于这题有很多解法,例如KMP,Hash啥的……但是既然这题有AC自动机的标签,那么我们肯定要用AC自动机去解决对吧?

然后冥思苦想没有结果……滚去看题解,然后发现这题AC自动机的做法甚是巧妙

首先将模板串按'*'分段,每一段建立一个AC自动机,每个AC自动机里面的串按照'?'分成多个串建成一棵trie树

然后呢?我们考虑一下某个AC自动机的字符'abcd?abc?cd?abcd'

然后绿色的是终止节点(多个终止就开个vector),然后我们把其他串拿进来匹配后,每碰到一个绿色点,我们就让\(C[pos-End[p][i]]\)加1,其中pos是当前匹配位置(匹配串),p是AC自动机中位置,End[p]就是vector,这样处理完后,我们再次扫一遍匹配,看一下哪个位置的\(C[i]\)与段数相等,那么它就可以作为这段模板串的匹配起点

注意匹配的时候匹配串是不需要切成一段段再进去匹配的,你可以每次都整串匹配,但是需要开一个变量记录上一次匹配到的最靠前的位置,然后判断一下即可

最前面和最后面需要根据'*'的有无进行特判

匹配串在一个个AC自动机中不一定要匹配连续的一段,因为存在'*'这种高级玩意

  1. /*program from Wolfycz*/
  2. #include<cmath>
  3. #include<cstdio>
  4. #include<vector>
  5. #include<cstring>
  6. #include<iostream>
  7. #include<algorithm>
  8. #define inf 0x7f7f7f7f
  9. #define for_vec(it,x) for (vector<int>::iterator it=x.begin();it!=x.end();it++)
  10. using namespace std;
  11. typedef long long ll;
  12. typedef unsigned int ui;
  13. typedef unsigned long long ull;
  14. inline char gc(){
  15. static char buf[1000000],*p1=buf,*p2=buf;
  16. return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
  17. }
  18. inline int frd(){
  19. int x=0,f=1;char ch=gc();
  20. for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1;
  21. for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<1)+(x<<3)+ch-'0';
  22. return x*f;
  23. }
  24. inline int read(){
  25. int x=0,f=1;char ch=getchar();
  26. for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
  27. for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
  28. return x*f;
  29. }
  30. inline void print(int x){
  31. if (x<0) putchar('-'),x=-x;
  32. if (x>9) print(x/10);
  33. putchar(x%10+'0');
  34. }
  35. const int N=1e5;
  36. int pos[N+10],pos_cnt,lenS;
  37. bool BGN,END;
  38. struct S1{
  39. int trie[N+10][26],fail[N+10];
  40. int tot,root,num,L;
  41. vector<int>End[N+10];
  42. void insert(char *s,int l,int r){
  43. static char T[N+10];
  44. for (int i=l;i<r;i++) T[i-l]=s[i];
  45. int len=r-l,p=root; T[len++]='?';
  46. for (int i=0;i<len;i++){
  47. while (T[i]=='?'&&i<len){
  48. if (i&&T[i-1]!='?') End[p].push_back(i-1),num++;
  49. p=root,i++;
  50. }
  51. if (i>=len) break;
  52. if (!trie[p][T[i]-'a']) trie[p][T[i]-'a']=++tot;
  53. p=trie[p][T[i]-'a'];
  54. }L=--len;
  55. }
  56. void make_fail(){
  57. static int h[N+10];
  58. int head=1,tail=0;
  59. for (int i=0;i<26;i++) if (trie[root][i]) h[++tail]=trie[root][i];
  60. for (;head<=tail;head++){
  61. int Now=h[head];
  62. for_vec(it,End[fail[Now]]) End[Now].push_back(*it);
  63. for (int i=0;i<26;i++){
  64. if (trie[Now][i]){
  65. int son=trie[Now][i];
  66. fail[son]=trie[fail[Now]][i];
  67. h[++tail]=son;
  68. }else trie[Now][i]=trie[fail[Now]][i];
  69. }
  70. }
  71. }
  72. bool check(char *s,bool Fir,bool Lst){
  73. static int cnt[N+10];
  74. memset(cnt,0,sizeof(cnt));
  75. int len=strlen(s),p=root;
  76. for (int i=0;i<len;i++){
  77. p=trie[p][s[i]-'a'];
  78. for_vec(it,End[p]) if (i>=*it) cnt[i-*it]++;
  79. }
  80. for (int i=0;i<len;i++){
  81. if (cnt[i]!=num) continue;
  82. if (!pos_cnt){
  83. if (!BGN&&Fir&&i) break;
  84. if (!END&&Lst&&len-i!=L) break;
  85. pos[++pos_cnt]=i+L;
  86. return 1;
  87. }else{
  88. if (i<pos[pos_cnt]) continue;
  89. if (!END&&Lst&&len-i!=L) break;
  90. pos[++pos_cnt]=i+L;
  91. return 1;
  92. }
  93. }
  94. return 0;
  95. }
  96. }AC[10];//Aho-Corasick automaton
  97. char s[N+10];
  98. int main(){
  99. scanf("%s",s);
  100. int len=strlen(s),tot=0; lenS=len;
  101. BGN=s[0]=='*',END=s[len-1]=='*',s[len++]='*';
  102. for (int i=0,Last=0;i<len;i++){
  103. if (s[i]=='*'){
  104. if (i>Last) AC[tot++].insert(s,Last,i);
  105. Last=i+1;
  106. }
  107. }
  108. for (int i=0;i<tot;i++) AC[i].make_fail();
  109. for (int Q=read();Q;Q--){
  110. if (!len){
  111. printf("NO\n");
  112. continue;
  113. }
  114. if (!tot){
  115. printf("YES\n");
  116. continue;
  117. }
  118. memset(s,0,sizeof(s));
  119. memset(pos,0,sizeof(pos)); pos_cnt=0;
  120. scanf("%s",s);
  121. bool flag=1;
  122. for (int i=0;i<tot;i++){
  123. if (!AC[i].check(s,i==0,i==tot-1)){
  124. flag=0;
  125. break;
  126. }
  127. }
  128. printf(flag?"YES\n":"NO\n");
  129. }
  130. return 0;
  131. }

[CQOI2014]通配符匹配的更多相关文章

  1. 「题解报告」 P3167 [CQOI2014]通配符匹配

    「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...

  2. bzoj 3507: [Cqoi2014]通配符匹配

    Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可 ...

  3. BZOJ3507 [Cqoi2014]通配符匹配

    题意 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号("*"),可以匹配0个及以上的任意字符:另一个是问号(" ...

  4. P3167 [CQOI2014]通配符匹配 题解

    题目 题目大意 给出一个字符串,其中包含两种通配符 ‘?’和 ‘*’ ,‘?’可以代替一个字符,‘*’可以代替一个字符串(长度可以为0) 然后给出几个字符转,判断能否用给出的字符串表示出来 样例解释 ...

  5. BZOJ3507 [Cqoi2014]通配符匹配 【哈希 + 贪心】

    题目 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个 是星号(""'),可以匹配0个及以上的任意字符:另一个是问号(&quo ...

  6. 【bzoj3570】 Cqoi2014—通配符匹配

    http://www.lydsy.com/JudgeOnline/problem.php?id=3507 (题目链接) 题意 给出一个主串,里面有些通配符,'*'可以代替任意字符串或者消失,'?'可以 ...

  7. [BZOJ3507][CQOI2014]通配符匹配(DP+Hash)

    显然f[i][j]表示S匹配到第i个通配符,T匹配到第j个字符,是否可行. 一次一起转移两个通配符之间的所有字符,Hash判断. 稍微有点细节.常数极大卡时过排名倒数,可能是没自然溢出的原因. #in ...

  8. [bzoj3507 Cqoi2014]通配符匹配 (hash+DP)

    传送门 Solution 显然用哈希233 设\(f[i][j]\)表示第i个通配符和当前第j个字符是否匹配 考虑两种通配符的特性,直接转移即可 Code #include <cstdio> ...

  9. P3167 [CQOI2014]通配符匹配

    吐槽 本来是去写AC自动机的,然后发现数据范围每个串100000,有100个串(???),连塞进trie树里都塞不进去,玩个鬼的AC自动机啊,tag不要乱打啊 最后拿字符串hash+爆搜一发搜过去了. ...

随机推荐

  1. GitHub 上值得关注的 iOS 开源项目

    GitHub 上值得关注的 iOS 开源项目 原文链接:http://www.jianshu.com/p/e5dfe1a09611 GitHub 上值得关注的 iOS 开源项目 —— 由 红旗下的蛋  ...

  2. JAVA WEB学习笔记(一):JDK的安装及环境变量的配置

    一.JDK的安装. JDK可以在Oracle(甲骨文)的官网下载,连接地址:http://www.oracle.com/technetwork/java/javase/downloads/index- ...

  3. 关于HTTP1.1的长连接

    HTTP是一个构建在传输层的TCP协议之上的应用层的协议,在这个层的协议,是一种网络交互须要遵守的一种协议规范. HTTP1.0的短连接 HTTP 1.0规定浏览器与server仅仅保持短暂的连接.浏 ...

  4. SignatureDoesNotMatch REST接口 在任何时间、任何地点、任何互联网设备上 在Header中包含签名

    PutObject_关于Object操作_API 参考_对象存储 OSS-阿里云 https://help.aliyun.com/document_detail/31978.html OSS API ...

  5. Marking as slave lost.

    Spark on Yarn提交任务时报ClosedChannelException解决方案_服务器应用_Linux公社-Linux系统门户网站 http://www.linuxidc.com/Linu ...

  6. filter、servlet、interceptor的执行顺序

    1. Filter可认为是Servlet的一种“变种”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链.它与Servlet的区别在于:它不能 ...

  7. 汉字与区位码互转(天天使用Delphi的String存储的是内码,Windows记事本存储的文件也是内码),几个常见汉字的各种编码,utf8与unicode的编码在线查询,附有读书笔记 good

    汉=BABA(内码)=-A0A0=2626(区位码)字=D7D6(内码)=-A0A0=5554(区位码) 各种编码查询表:http://bm.kdd.cc/ 汉(记住它,以后碰到内存里的数值,就会有敏 ...

  8. YTU 2424: C语言习题 字符串比较

    2424: C语言习题 字符串比较 时间限制: 1 Sec  内存限制: 128 MB 提交: 1042  解决: 613 题目描述 写一函数,实现两个字符串的比较.即自己写一个strcmp函数,函数 ...

  9. 解决post乱码之web.xml

    <!-- 解决post乱码 --> <filter> <filter-name>characterEncodingFilter</filter-name> ...

  10. 【旧文章搬运】遍历EPROCESS中的ActiveProcessLinks枚举进程

    原文发表于百度空间,2008-7-25========================================================================== 前面对PEB ...