题目:Wildcard

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3901

题意:给一个原串(只含小写字母)和一个模式串(含小写字母、?、* ,*号可替换为0到无穷个任意字母,?可替换为一个任意字母),问两个字符串是否匹配。

思路:

  这是经典题吧。。。

  AC自动机。(网上大多代码是错的,用普通kmp是不行的,不知道修改过后可不可以)。

  HDU已经加强数据了,可我前一个代码abcd ?显示是YES居然还过了,看来数据还是有点弱啊。

  *号的处理是很容易的,只需要把模式串以*号为分界分解开来,然后除了最后一段,其他尽量匹配靠前的原串子串就差不多了,比如ab*cd*ef*gh,那么原串必须以ab开头、gh结尾、然后找到最前的cd、再找到ef,如果互相不重叠就OK。

  比较难的是?的处理了,*分解开模式串分别处理。现在,根据?分解,将分解后的字符串(不含?号了)构建AC自动机。

  比如串A:abcd?abc?cd?abcd,构建AC自动机,然后在结束点记录他在串A中的位置。

  红色为根,黄色为每一个结束点,这里的fail指针与普通AC自动机相同

  现在我们创建一个数组cnt,对应原串的每一位,让原串在自动机上跑,如果遇到黄点cnt[当前位置-记录的值+1]++,比如遇到abcd,那说明原串当前位置前四位一定是abcd,满足这一段,而如果有某一个cnt值等于4,就说明他满足了所有段,那么他可以作为串A匹配的起点,a b c d _ a b c _ c d _ a b c d,只有上面这种情况才会使第一个a的cnt值为4,而cnt等于4,当前位就是该次匹配满足的最前位置了。

  上一段理解后,题目就可以得解了,注意细节就是了。

AC代码:

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<set>
#include<map>
#include<list>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define lson rt<<1
#define rson rt<<1|1
#define N 100010
#define M 26
#define Mod 1000000007
#define LL long long
#define INF 0x7fffffff
#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
#define For(i,f_start,f_end) for(int i=f_start;i<f_end;i++)
#define REP(i,f_end,f_start) for(int i=f_end;i>=f_start;i--)
#define Rep(i,f_end,f_start) for(int i=f_end;i>f_start;i--)
#define MT(x,i) memset(x,i,sizeof(x))
#define gcd(x,y) __gcd(x,y)
const double PI = acos(-); struct Node
{
vector<int> d;
int fail;
int next[M];
}v[N];
int vNum; void Init()
{
v[].fail = -;
FOR(i,,){
v[].next[i]=-;
}
vNum=;
} int create()
{
v[vNum].d.clear();
v[vNum].fail=-;
for(int i=;i<M;i++) v[vNum].next[i]=-;
return vNum++;
} int getPos(char c)
{
return c-'a';
} int add(char *s)
{
int i,ret=,p=;
for(i=;s[i];i++){
if(s[i]=='?'){
if(p!=){
ret++;
v[p].d.push_back(i);
p=;
}
}
int pos = getPos(s[i]);
if(v[p].next[pos]==-) v[p].next[pos]=create();
p = v[p].next[pos];
}
if(p!=){
ret++;
v[p].d.push_back(i);
}
return ret;
} queue<int> q;
void makeFail()
{
q.push();
while(q.size())
{
int p=q.front();
q.pop();
for(int i=;i<M;i++)
{
if(v[p].next[i]!=-)
{
int t=v[p].fail;
while()
{
if(t == -) // p 已经是根了
{
v[v[p].next[i] ].fail = ;
break;
}
else if(v[t].next[i] != -)
{
v[v[p].next[i] ].fail = v[t].next[i];
break;
}
else t=v[t].fail;
}
if(t!=-){
for(int j=;j<v[t].d.size();j++){
v[p].d.push_back(v[t].d[j]);
}
}
q.push(v[p].next[i]);
}
}
}
} int cnt[N];
int match(char *s,char *s1)
{
Init();
int duan = add(s1);
if(duan==) return ; makeFail(); //printf("%s %s %d\n",s,s1,duan); memset(cnt,,sizeof(cnt));
int i,p=;
for(i=;s[i];i++){
int pos = getPos(s[i]);
if(p==-){
p=;
continue;
}
if(v[p].next[pos]==-){
p = v[p].fail;
i--;
continue;
}
p = v[p].next[pos];
for(int j=;j<v[p].d.size();j++){
cnt[i-v[p].d[j]+]++;
if(cnt[i-v[p].d[j]+]==duan) return i-v[p].d[j]+;
}
}
return -;
} char s[N],s1[N],s2[N];
bool solve(char *s,char *s1)
{
int ls=strlen(s),ps=;
int i,len=,flag=;
for(i=;s1[i];i++){
if(s1[i]=='*'){
if(len!=){
s2[len]=;
int qi = match(s+ps,s2);
if(qi==-) return false;
if(flag== && qi!=) return false;
ps += qi + len;
if(ps>ls) return false;
len = ;
}
flag=;
}
else s2[len++]=s1[i];
}
if(len!=){
len--;
for(i=ls-;i>=ps && len>=;i--){
if(s2[len]!='?' && s2[len]!=s[i]) return false;
len--;
}
if(i>=ps && flag== || len>=) return false;
}
return true;
} int main()
{
while(scanf("%s%s",s,s1)!=EOF)
{
printf("%s\n",solve(s,s1)?"YES":"NO");
}
return ;
}

HDU 3901 Wildcard的更多相关文章

  1. 【HDOJ】3901 Wildcard

    1. 题目描述有两个长度为$10^5$的字符串,其中一个仅包含小写字母,称之为源串:另一个包含?与*通配符的模式串,并且通配符的个数不超过10.求模式串是否能匹配源串? 2. 基本思路这其实是一道Re ...

  2. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  3. cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'mvc:annotation-driven'.

    spring 配置文件报错报错信息:cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be ...

  4. [LeetCode] Wildcard Matching 外卡匹配

    Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. ...

  5. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  6. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  7. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  8. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  9. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

随机推荐

  1. js报错:Uncaught SyntaxError: Unexpected string

    一.问题 今天在写jsp页面时,发现加上某段代码后,页面的其它js就失效了,死活出不来,然后打开谷歌浏览器发现,页面js报如下错误: Uncaught SyntaxError: Unexpected ...

  2. Pythoy 数据类型序列化——json&pickle 模块

    Pythoy 数据类型序列化--json&pickle 模块 TOC 什么是序列化/反序列化 pickle 模块 json 模块 对比json和pickle json.tool 命令行接口 什 ...

  3. WEB 实时推送技术的总结

    前言 随着 Web 的发展,用户对于 Web 的实时推送要求也越来越高 ,比如,工业运行监控.Web 在线通讯.即时报价系统.在线游戏等,都需要将后台发生的变化主动地.实时地传送到浏览器端,而不需要用 ...

  4. TS学习随笔(三)->接口

    终于来到了比较重要的知识,接口,有多重要呢,反正是很重要好啵 在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型. 那什么是接口呢,在面向对象语言中,接口(Interf ...

  5. Dynamics 365使用Execute Multiple Request删除系统作业实体记录

    摘要: 本人微信公众号:微软动态CRM专家罗勇 ,回复295或者20190112可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me ...

  6. MyCat | 分库分表实践

    引言 先给大家介绍2个概念:数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式. 切分模式 一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称之 ...

  7. 轨迹系列5——验证轨迹GPS坐标转换为本地坐标的四/七参数是否准确的一种方案

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1. 背景 目前对多个项目轨迹不准确的情况做了排查,发现导致轨迹偏移百分 ...

  8. 仿9GAG制作过程(五)

    有话要说: 在做完了数据展示功能之后,就想着完善整个APP.发现现在后台非常的混乱,有好多点都不具备,比方说:图片应该有略缩图和原图,段子.评论.点赞应该联动起来,段子应该有创建时间等. 于是就重新设 ...

  9. Netty学习笔记(二) 实现服务端和客户端

    在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...

  10. C++17剖析:string在Modern C++中的实现

    概述 GCC 8.2提供了两个版本的std::string:一个是基于Copy On Write的,另一个直接字符串拷贝的.前者针对C++11以前的,那时候没有移动构造,一切以效率为先,需要使用COW ...