COJN 0558 800600带通配符的字符串匹配

时间:2023-03-09 16:36:31
COJN 0558 800600带通配符的字符串匹配
800600带通配符的字符串匹配
难度级别:B; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

通配符是一类键盘字符,当我们不知道真正字符或者不想键入完整名字时,常常使用通配符代替一个或多个真正字符。通配符有问号(?)和星号(*)等,其中,“?”可以代替一个字符,而“*”可以代替零个或多个字符。你的任务是,给出一个带有通配符的字符串和一个不带通配符的字符串,判断他们是否能够匹配。例如,1?456 可以匹配 12456、13456、1a456,但是却不能够匹配23456、1aa456;2*77?8可以匹配 24457798、237708、27798。

输入
输入有两行,每行为一个不超过20个字符的字符串,第一行带通配符,第二行不带通配符
输出
如果两者可以匹配,就输出“matched”,否则输出“not matched”
输入示例
1*456?
11111114567
输出示例
matched
其他说明
NOI练习库中的试题。

题解:一道神题。。。。。。。。QAQ。。。太hentai了吧。。。QAQ。。。

一开始随便写了一发:

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+;
char s[maxn],t[maxn];
inline int read(){
int x=,sig=;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=;
for(;isdigit(ch);ch=getchar())x=*x+ch-'';
return sig?x:-x;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
void init(){
scanf("%s%s",s,t);bool flag=true;
int n1=strlen(s),n2=strlen(t);
int i,j;
for(i=,j=;i<n1;i++){
//printf("%d %d\n",i,j);
if(s[i]=='?'){
if(j<n2){j++;continue;}
else{flag=false;break;}
}
else if(s[i]=='*'){
while(j<n2&&s[i+]!=t[j])j++;j--;
if(j<n2){j++;continue;}
else{flag=false;break;}
}
else{
if(s[i]==t[j]){j++;continue;}
else{flag=false;break;}
}
}
if(flag&&j==n2)puts("matched");
else puts("not matched");
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){init();work();print();return ;}

发现WA的飞起啊!!!比如12345******???????456****之类的。。。。。

然后发现不会做了。。。。星号的匹配实在太恶心了吧。。。。

最后得到正解。。。。其实,星号的作用是分割两个字符串,那么当星号后的东东不匹配,窝萌就要重新分割,于是想到了AC自动机的fail指针的思想,窝萌可以为每个星号打个标记,当不匹配的时候就往回匹配,就好了。。。。。

写起来真的是hentai啊!!!细节太多了啊!!!

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+;
bool match(char*s,char*t){
if(t==NULL||s==NULL)return false;
int n1=strlen(t),n2=strlen(s),mark=,p1=,p2=;
while(p1<n1&&p2<n2){
if(s[p2]=='?'){p1++;p2++;continue;}
if(s[p2]=='*'){p2++;mark=p2;continue;}
if(t[p1]!=s[p2]){
if(p1==&&p2==)return false;
p1-=p2-mark-;p2=mark;continue;
}p1++;p2++;
}
if(p2==n2){
if(p1==n1)return true;
if(s[p2-]=='*')return true;
}
for(;p2<n2;p2++)if(s[p2]!='*')return false;
return true;
}
inline int read(){
int x=,sig=;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=;
for(;isdigit(ch);ch=getchar())x=*x+ch-'';
return sig?x:-x;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
char s[maxn],t[maxn];
void init(){
cin.getline(s,);
cin.getline(t,);
if(match(s,t))puts("matched");
else puts("not matched");
return;
}
void work(){
return;
}
void print(){
return;
}
int main(){init();work();print();return ;}