3507: [Cqoi2014]通配符匹配

Time Limit: 10 Sec  Memory Limit: 128 MB

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%的数据
  ·字符串长度不超过1 00000
  ·  1 <=n<=100
  ·通配符个数不超过10

题解:

考场打暴力打炸了……

不过在后来改题的时候我发现了暴力思路的一个大问题……我们还是直接讲正解吧

题目给的通配符有2种,一种是’*’,它可以伸展;一种是‘?’,它的长度固定;

不难发现,给我们的处理带来难度的是'*',因为他的长度不确定;

但转念一想,如果除了*,其他的都能匹配,那*也就能匹配了.

注意到通配符个数<=10,那么我们可以先按照*,把原串分成一些包含'?'和字母的段.

而对于每一段,只要其中的所有小字符串成功匹配,并且符合'?'对长度的要求,这一段就匹配成功了

所以我们再在每一段里,按照'?'再分为几小块只含字母的串,并且分别求出hash值;同时求出文本串的hash值.

在匹配的时候,对于某一段,枚举起点,看在这一段在哪里可以匹配.

由于对于段间的枚举,影响因素只有*,所以匹配点肯定越靠前越好,因此这里可以贪心,即找到最靠前的匹配点即可停止.

而对于段内比较,利用刚才求的hash值比较就好.

代码见下:

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
using namespace std;
typedef unsigned long long LL;
const int N=;
const int mod1=;
int n,lens,len,cnt,cnt1[];
char s[N],text[N];
LL block[][],h[N],mi[N];
int l[][],num[];
inline LL g_hash(int l,int r){return h[r]-h[l-]*mi[r-l+];}
inline bool match(int i,int k)
{
for(int j=;j<=num[k];j++)
{
if(l[k][j]==){i++;continue;}
if(block[k][j]!=g_hash(i,i+l[k][j]-))return ;
i+=l[k][j]+;
}
return ;
}
bool judge()
{
if(!cnt)
{
if(len!=lens)return ;
for(int i=;i<=len;i++)
if(s[i]!=text[i]&&s[i]!='?')return ;
return ;
}
if(len<(cnt1[]-)+(lens-cnt1[cnt]))return ;
for(int i=;i<cnt1[];i++)if(s[i]!=text[i]&&s[i]!='?')return ;
for(int i=lens,j=len;i>cnt1[cnt];i--,j--)if(s[i]!=text[j]&&s[i]!='?')return ;
for(int i=;i<=len;i++)
h[i]=h[i-]*mod1+text[i];
int i=cnt1[],line=len-(lens-cnt1[cnt])+;
for(int k=;k<=cnt;k++)
{
for(;i<=line;i++)
if(match(i,k))break;
i+=cnt1[k]-cnt1[k-]-;
if(i>line)return ;
}
return ;
}
int main()
{
scanf("%s",s+);lens=strlen(s+);
mi[]=;for(int i=;i<=lens;i++)mi[i]=mi[i-]*mod1;
for(int i=;i<=lens;i++)
if(s[i]=='*')cnt1[++cnt]=i;
for(int i=;i<=cnt;i++)
{
num[i]=;
for(int j=cnt1[i-]+;j<cnt1[i];j++)
{
if(s[j]=='?'){num[i]++;continue;}
l[i][num[i]]++;
block[i][num[i]]=block[i][num[i]]*mod1+s[j];
}
}
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",text+);len=strlen(text+);
if(judge())printf("YES\n");
else printf("NO\n");
}
}

BZOJ3507

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

  1. [CQOI2014][bzoj3507] 通配符匹配 [字符串hash+dp]

    题面 传送门 思路 0x01 KMP 一个非常显然而优秀的想法:把模板串按照'*'分段,然后对于每一段求$next$,'?'就当成可以对于任意字符匹配就行了 对于每个文本串,从前往后找第一个可以匹配的 ...

  2. 【BZOJ3507】通配符匹配(哈希,动态规划)

    [BZOJ3507]通配符匹配(哈希,动态规划) 题面 BZOJ 题解 对于匹配唯一存在影响的只有通配符,而\(?\)的影响也并不大,所以唯一需要仔细考虑的是\(*\). 考虑一个\(dp\),设\( ...

  3. 【BZOJ-3507】通配符匹配 DP + Hash

    3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 372  Solved: 156[Submit][Statu ...

  4. BZOJ3507 [Cqoi2014]通配符匹配

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

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

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

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

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

  7. [Swift]LeetCode44. 通配符匹配 | Wildcard Matching

    Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '? ...

  8. LeetCode(44): 通配符匹配

    Hard! 题目描述: 给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配. '?' 可以匹配任何单个字符. '*' 可以匹配任意字符串(包括空字符串). ...

  9. [LeetCode][Facebook面试题] 通配符匹配和正则表达式匹配,题 Wildcard Matching

    开篇 通常的匹配分为两类,一种是正则表达式匹配,pattern包含一些关键字,比如'*'的用法是紧跟在pattern的某个字符后,表示这个字符可以出现任意多次(包括0次). 另一种是通配符匹配,我们在 ...

随机推荐

  1. 润乾报表整合到Tomcat服务器的部署过程

    转载自:http://www.cnblogs.com/avivaye/archive/2012/11/16/2773681.html 使用第三方的报表设计器/服务器来快速的开发报表. 润乾服务器是使用 ...

  2. JS基础循环语句练习

    最近这几天一直在做题做题做题,很恶心,很头疼,都快吐了,但是自己的逻辑还是初见成效的,很久不动脑了,有点锈住了,大家也一起来开发下自己的大脑 有关简单排序的小循环 <script> var ...

  3. Android开发笔记——图片缓存、手势及OOM分析

    把图片缓存.手势及OOM三个主题放在一起,是因为在Android应用开发过程中,这三个问题经常是联系在一起的.首先,预览大图需要支持手势缩放,旋转,平移等操作:其次,图片在本地需要进行缓存,避免频繁访 ...

  4. 强化学习读书笔记 - 09 - on-policy预测的近似方法

    强化学习读书笔记 - 09 - on-policy预测的近似方法 参照 Reinforcement Learning: An Introduction, Richard S. Sutton and A ...

  5. java计算两个日期之间的天数,排除节假日和周末

    如题所说,计算两个日期之前的天数,排除节假日和周末.这里天数的类型为double,因为该功能实现的是请假天数的计算,有请一上午假的为0.5天. 不够很坑的是每个日期都要查询数据库,感觉很浪费时间. 原 ...

  6. Vue 项目在其他电脑 npm run dev 运行报错的解决方法

    一个 Vue 项目从一台电脑上传到 github 上之后,再另外一台电脑上 git clone .并使用 npm run dev 或 npm run start 发生以下报错的解决方法.   报错原因 ...

  7. 【python 3.6】python读取json数据存入MySQL(一)

    整体思路: 1,读取json文件 2,将数据格式化为dict,取出key,创建数据库表头 3,取出dict的value,组装成sql语句,循环执行 4,执行SQL语句 #python 3.6 # -* ...

  8. 【第七章】MySQL数据库备份-物理备份

    一.数据库备份 备份的目的: 备份: 能够防止由于机械故障以及人为误操作带来的数据丢失,例如将数据库文件保存在了其它地方. 冗余: 数据有多份冗余,但不等备份,只能防止机械故障还来的数据丢失,例如主备 ...

  9. mtv网站架构模式适合企业网站应用吗?

    mtv网站架构模式适合企业网站应用吗?有时候在思考这样一个问题. 从开发角度来说,本来mvc的进度慢了些,如果在数据库管理方面用sql的话,管理起来也不很方便.小企业网本来数据就不很多,也没什么太多安 ...

  10. 在香港网站使用工商银行的MasterCard,工商银行所犯的低级的错误,金融安全何在