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。。。
一开始随便写了一发:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(‘ ‘) 8 #define ENT putchar(‘\n‘) 9 using namespace std; 10 const int maxn=20+5; 11 char s[maxn],t[maxn]; 12 inline int read(){ 13 int x=0,sig=1;char ch=getchar(); 14 for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)sig=0; 15 for(;isdigit(ch);ch=getchar())x=10*x+ch-‘0‘; 16 return sig?x:-x; 17 } 18 inline void write(int x){ 19 if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x; 20 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 21 for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return; 22 } 23 void init(){ 24 scanf("%s%s",s,t);bool flag=true; 25 int n1=strlen(s),n2=strlen(t); 26 int i,j; 27 for(i=0,j=0;i<n1;i++){ 28 //printf("%d %d\n",i,j); 29 if(s[i]==‘?‘){ 30 if(j<n2){j++;continue;} 31 else{flag=false;break;} 32 } 33 else if(s[i]==‘*‘){ 34 while(j<n2&&s[i+1]!=t[j])j++;j--; 35 if(j<n2){j++;continue;} 36 else{flag=false;break;} 37 } 38 else{ 39 if(s[i]==t[j]){j++;continue;} 40 else{flag=false;break;} 41 } 42 } 43 if(flag&&j==n2)puts("matched"); 44 else puts("not matched"); 45 return; 46 } 47 void work(){ 48 return; 49 } 50 void print(){ 51 return; 52 } 53 int main(){init();work();print();return 0;}
发现WA的飞起啊!!!比如12345******???????456****之类的。。。。。
然后发现不会做了。。。。星号的匹配实在太恶心了吧。。。。
最后得到正解。。。。其实,星号的作用是分割两个字符串,那么当星号后的东东不匹配,窝萌就要重新分割,于是想到了AC自动机的fail指针的思想,窝萌可以为每个星号打个标记,当不匹配的时候就往回匹配,就好了。。。。。
写起来真的是hentai啊!!!细节太多了啊!!!
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(‘ ‘) 8 #define ENT putchar(‘\n‘) 9 using namespace std; 10 const int maxn=20+5; 11 bool match(char*s,char*t){ 12 if(t==NULL||s==NULL)return false; 13 int n1=strlen(t),n2=strlen(s),mark=0,p1=0,p2=0; 14 while(p1<n1&&p2<n2){ 15 if(s[p2]==‘?‘){p1++;p2++;continue;} 16 if(s[p2]==‘*‘){p2++;mark=p2;continue;} 17 if(t[p1]!=s[p2]){ 18 if(p1==0&&p2==0)return false; 19 p1-=p2-mark-1;p2=mark;continue; 20 }p1++;p2++; 21 } 22 if(p2==n2){ 23 if(p1==n1)return true; 24 if(s[p2-1]==‘*‘)return true; 25 } 26 for(;p2<n2;p2++)if(s[p2]!=‘*‘)return false; 27 return true; 28 } 29 inline int read(){ 30 int x=0,sig=1;char ch=getchar(); 31 for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)sig=0; 32 for(;isdigit(ch);ch=getchar())x=10*x+ch-‘0‘; 33 return sig?x:-x; 34 } 35 inline void write(int x){ 36 if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x; 37 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 38 for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return; 39 } 40 char s[maxn],t[maxn]; 41 void init(){ 42 cin.getline(s,21); 43 cin.getline(t,21); 44 if(match(s,t))puts("matched"); 45 else puts("not matched"); 46 return; 47 } 48 void work(){ 49 return; 50 } 51 void print(){ 52 return; 53 } 54 int main(){init();work();print();return 0;}
时间: 2024-10-08 10:28:47