码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-07-25 13:33:51      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:

 

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;}

 

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

标签:

原文地址:http://www.cnblogs.com/chxer/p/4675653.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!