LuoguP3167通配符匹配
题意
本题的意思就是给出一段带有 $ ? $ 与 \(*\) 的字符串
(在下面称为\(s\)),
$ ? $ 必须占据一个字符位置, \(*\) 可以占据任意位置,
求下面给出几段(在下面称为\(ss\))中能够匹配的字符串。
思路
前言
本题最可恶的一点是,如果s的第一段/最后一段是字符,那么ss中最开始/最后也必须是一样的字符。
另外,本题我使用了hash + 前缀,如果不太熟悉的话可以了解一下~传送门
举个栗子~
如样例,s为*aca?ctc,我们就可以将它分为
\(*\) ,aca, $ ? $ ,ctc 共四段。
对于每一段,我们用一个add数组来判断它的种类,
用co记录它的段数,字符串对应2,\(*\) 对应1,$ ? $ 对应0:
scanf("%s",s+1);lens=strlen(s+1);
if(s[1]<'a'||s[1]>'z')co=0;else add[1]=2;
for(int i=1;i<=lens;i++)
{
if(s[i]>='a'&&s[i]<='z')
{
len[co]++;
f[co]=f[co]*131+s[i];
}
else if(s[i]=='*') {add[++co]=1;if(i!=lens&&s[i+1]>='a'&&s[i+1]<='z')add[++co]=2;}
else{co++;if(i!=lens&&s[i+1]>='a'&&s[i+1]<='z')add[++co]=2;}
}
注意,由于开头字符不好判断,所以这里加了一个特判,
来记录开头是字符串的情况。
判断
预处理好了,那么,如何进行判断呢?
这里,我用了 $ doit $ 与 \(ask\) 两个自定义函数,
doit用来对可以自由匹配的字符种类进行判断处理,
ask用来对“ ? ”后的字符进行判断处理。
两个函数中都使用了key,k两个参数,
key记录了到哪个字符(指针),k记录了到第几段。
对于doit:
void doit(int key,int k)
{
if(k>co){can=1;return;}//段数数完了,说明满足条件;
if(add[k]==2)//字符
{
for(int i=key+len[k]-1;i<=le;i++)
if(ff[i]-ff[i-len[k]]*p[len[k]]==f[k])//寻找符合的解进行doit;
{doit(i+1,k+1);if(can)return;}
return;
}
if(add[k]==1)//星号
{
doit(key,k+1);
if(can)return;
return;
}
if(add[k]==0)//问号
{
ask(key+1,k+1);return;
}
}
对于ask:
void ask(int key,int k)
{
if(k>co){can=1;return;}
if(add[k]==2)
{
if(ff[key+len[k]-1]-ff[key-1]*p[len[k]]==f[k])doit(key+len[k],k+1);
}
else
{
if(add[k]==1){if(add[k+1]==0){
for(int i=key+2;i<=le;i++)
if(ff[i+len[k+2]-1]-ff[i-1]*p[len[k+2]]==f[k+2])doit(i+len[k+2],k+3);}
doit(key,k+1);}//星号,判断下一个是不是问号
如果是问号就要找到能够匹配的子串进行doit;
else ask(key+1,k+1);//问号继续ask;
}
}
收尾
到这里,万事俱备,只欠东风,进行我们华丽的结束吧~
接下来就该读入与判断了:
p[0]=1;
for(int i=1;i<=100000;i++)p[i]=p[i-1]*131;
int n=read();
while(n--)
{can=0;
scanf("%s",ss+1);le=strlen(ss+1);
for(int i=1;i<=le;i++)ff[i]=ff[i-1]*131+ss[i];
if(add[1]==2)if(ff[len[1]]-ff[0]*p[len[1]]!=f[1]){printf("NO\n");continue;}//前言中说的特殊情况
if(add[co]==2)if(ff[le]-ff[le-len[co]]*p[len[co]]!=f[co]){printf("NO\n");continue;}
doit(1,1);
if(can)printf("YES\n");else printf("NO\n");
}
return 0;
CODE
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define ull unsigned long long
int read(){int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x;}
char s[100005],ss[100005];
int lens,len[25],co=1,le,k,key,cnt,add[25];bool can;
ull f[25],ff[100010],p[100010];
void ask(int,int);
void doit(int,int);
void ask(int key,int k)
{
if(k>co){can=1;return;}
if(add[k]==2)
{
if(ff[key+len[k]-1]-ff[key-1]*p[len[k]]==f[k])doit(key+len[k],k+1);
}
else
{
if(add[k]==1){if(add[k+1]==0){for(int i=key+2;i<=le;i++)if(ff[i+len[k+2]-1]-ff[i-1]*p[len[k+2]]==f[k+2])doit(i+len[k+2],k+3);}doit(key,k+1);}
else ask(key+1,k+1);
}
}
void doit(int key,int k)
{
if(k>co){can=1;return;}
if(add[k]==2)
{
for(int i=key+len[k]-1;i<=le;i++)
if(ff[i]-ff[i-len[k]]*p[len[k]]==f[k])
{doit(i+1,k+1);if(can)return;}
return;
}
if(add[k]==1)
{
doit(key,k+1);
if(can)return;
return;
}
if(add[k]==0)
{
ask(key+1,k+1);return;
}
}
int main()
{
scanf("%s",s+1);lens=strlen(s+1);
if(s[1]<'a'||s[1]>'z')co=0;else add[1]=2;
for(int i=1;i<=lens;i++)
{
if(s[i]>='a'&&s[i]<='z')
{
len[co]++;
f[co]=f[co]*131+s[i];
}
else if(s[i]=='*') {add[++co]=1;if(i!=lens&&s[i+1]>='a'&&s[i+1]<='z')add[++co]=2;}
else{co++;if(i!=lens&&s[i+1]>='a'&&s[i+1]<='z')add[++co]=2;}
}
p[0]=1;
for(int i=1;i<=100000;i++)p[i]=p[i-1]*131;
int n=read();
while(n--)
{can=0;
scanf("%s",ss+1);le=strlen(ss+1);
for(int i=1;i<=le;i++)ff[i]=ff[i-1]*131+ss[i];
if(add[1]==2)if(ff[len[1]]-ff[0]*p[len[1]]!=f[1]){printf("NO\n");continue;}
if(add[co]==2)if(ff[le]-ff[le-len[co]]*p[len[co]]!=f[co]){printf("NO\n");continue;}
doit(1,1);
if(can)printf("YES\n");else printf("NO\n");
}
return 0;
}
结语
这道题我也调了有好久了,甚至都有些舍不得了,所以写下了本篇题解,也是我的第一篇题解
如果对你有帮助,求个赞qwq
LuoguP3167通配符匹配的更多相关文章
- bzoj 3507: [Cqoi2014]通配符匹配
Description 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号(“”’),可以匹配0个及以上的任意字符:另一个是问号(“?”),可 ...
- 【BZOJ-3507】通配符匹配 DP + Hash
3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 372 Solved: 156[Submit][Statu ...
- [Swift]LeetCode44. 通配符匹配 | Wildcard Matching
Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '? ...
- 【BZOJ3507】通配符匹配(哈希,动态规划)
[BZOJ3507]通配符匹配(哈希,动态规划) 题面 BZOJ 题解 对于匹配唯一存在影响的只有通配符,而\(?\)的影响也并不大,所以唯一需要仔细考虑的是\(*\). 考虑一个\(dp\),设\( ...
- LeetCode(44): 通配符匹配
Hard! 题目描述: 给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配. '?' 可以匹配任何单个字符. '*' 可以匹配任意字符串(包括空字符串). ...
- [BZOJ3507]通配符匹配
3507: [Cqoi2014]通配符匹配 Time Limit: 10 Sec Memory Limit: 128 MB Description 几乎所有操作系统的命令行界面(CLI)中都支持文件 ...
- [LeetCode][Facebook面试题] 通配符匹配和正则表达式匹配,题 Wildcard Matching
开篇 通常的匹配分为两类,一种是正则表达式匹配,pattern包含一些关键字,比如'*'的用法是紧跟在pattern的某个字符后,表示这个字符可以出现任意多次(包括0次). 另一种是通配符匹配,我们在 ...
- WildcardMatching和Regex,通配符匹配和正则表达式匹配
WildcardMatching:通配符匹配 算法分析: 1. 二个指针i, j分别指向字符串.匹配公式. 2. 如果匹配,直接2个指针一起前进. 3. 如果匹配公式是*,在字符串中依次匹配即可. 注 ...
- BZOJ3507 [Cqoi2014]通配符匹配
题意 几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户.最常见的通配符有两个,一个是星号("*"),可以匹配0个及以上的任意字符:另一个是问号(" ...
随机推荐
- nginx的基本使用
下载: https://nginx.org/en/download.html Window下安装: 下载好了之后直接解压就行了.(解压目录切记别含有中文) 启动:1️⃣直接双击nginx.exe2️ ...
- Kubernetes 1.13.3 部署 Prometheus+Grafana-7.5.2(最新版本踩坑)
本教程直接在 Kubernetes 1.13.3 版本上安装 Prometheus 和 Grafana-7.5.2,至于它们的原理和概念就不再赘述,这里就直接开始操作. Git 下载相关 YAML 文 ...
- 软件测试跟踪工具Bugzilla的安装 - Linux版本
首先查看Linux当前版本 输入"uname -a ",可显示电脑以及操作系统的相关信息 输入"cat /proc/version",说明正在运行的内核版本 输 ...
- CTF-OldDriver-writeup
题目信息: 有个年轻人得到了一份密文,身为老司机的你能帮他看看么? 附件:enc.txt [{"c": 73660675747411714617220651332429160804 ...
- MyBatis学习笔记(一):MAVEN的下载,安装与环境配置和在IDEA中配置maven
一.下载 官网下载 :http://maven.apache.org/download.cgi 网速慢的也可以下载我配置好的国内阿里云仓库的.以下以我配置好的为例: 下载链接:https://pan. ...
- 关于hive核心
一.DDL数据定义 1.创建数据库 1)创建一个数据库,数据库在 HDFS 上的默认存储路径是/user/hive/warehouse/*.db. hive (default)> create ...
- CF1032G Chattering
CF1032G Chattering 题意 思路 对于每一个位置,它转移的范围是确定的. 对于一段可以走到的区间,我们可以求出区间中所有点再能走到区间范围. 于是这个就可以倍增进行转移. 如何快速求出 ...
- 插入排序(insertion_sort)——Python实现
# 插入排序 # 作用:对给出的n个顺序不定的数进行排序 # 输入:任意数组A # 输出:按顺序排列的数组A # 时间复杂度 n(n-1) 至 (n(n-1))/2 # 插入排序过程 # 第一 ...
- 【阅读笔记】Java核心技术卷一 #4.Chapter6
6 接口.lambda 表达式与内部类 6.1 接口 6.1.1 接口概念 接口绝不能含有实例域:但在接口中可以定义常量,被自动设为 public static final 接口中的所有方法自动地属于 ...
- thinkPHP5 5.0.23 远程代码执行漏洞
修改数据包 POST /index.php?s=captcha HTTP/1.1 Host: 192.168.49.2:8080 User-Agent: Mozilla/5.0 (Macintosh; ...