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。。。

一开始随便写了一发:

 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

COJN 0558 800600带通配符的字符串匹配的相关文章

openjudge6252 带通配符的字符串匹配

描述 通配符是一类键盘字符,当我们不知道真正字符或者不想键入完整名字时,常常使用通配符代替一个或多个真正字符.通配符有问号(?)和星号(*)等,其中,“?”可以代替一个字符,而“*”可以代替零个或多个字符. 你的任务是,给出一个带有通配符的字符串和一个不带通配符的字符串,判断他们是否能够匹配. 例如,1?456 可以匹配 12456.13456.1a456,但是却不能够匹配23456.1aa456: 2*77?8可以匹配 24457798.237708.27798. 输入输入有两行,每行为一个不

带通配符的字符串匹配问题

1 /* 2 不使用c,c++库,?表示任意一个,*表示>=0任意,匹配规则要求匹配最大的字符子串,例如a*d ,匹配abbdd而非abbd,即最大匹配字符串 3 input :abcadefg 4 reule : a?c 5 ouput : abc 6 7 input : newsadfanewfdsdsf 8 rule :new 9 output: new new(最后一个不带空格,中间用空格分隔) 10 11 input : breakfastfood 12 rule : f*d 13 o

带通配符的字符串匹配(动态规划)

OJ地址:http://noi.openjudge.cn/ch0206/6252/ 1 #include<string> 2 #include<cstdio> 3 #include<iostream> 4 using namespace std; 5 string A,B; 6 bool Judge(int a,int b); 7 void Init(); 8 int main() 9 { 10 // cin>>A>>B;//A with ? o

动态规划 | 带有通配符的字符串匹配(浅显易懂)

带有通配符的字符串匹配 一.Leetcode | 44 Wildcard Matching(只有一个字符串包含通配符) 题目很简单,就是说两个字符串,一个含有通配符,去匹配另一个字符串:输出两个字符串是否一致. 注意:'?'表示匹配任意一个字符,'*'表示匹配任意字符0或者多次 首先,我们想到暴力破解.如果从头到尾的破解,到第二个字符时,是否匹配成功取决于第一个字符是否匹配成功! 所以我们想到应该要用到动态规划: 既然用到动态规划,最重要的是设置初值 和找到递推式: 于是,我们开始分析初值怎么设

[OpenJudge]带有通配符的字符串匹配

#include <iostream> #include <stdlib.h> #include <string.h> using namespace std; /* 字符串匹配 ?代表一个字符(不能没有),*可以代表任意多个字符(可以为空) ?表示任意字符,也就是说?永远可以匹配成功,本质上,只要遇到?就一定匹配 *的本质,是分割字符串,即如果P=P1*P2,即P得匹配条件是匹配P1串之后,再匹配P2子串 */ //@param  src[], 带匹配的字符串 //@

含有通配符的字符串匹配

字符串匹配问题,给定两个字符串.求字符串2.在字符串1中的最先匹配结果.字符串2中能够存在'*'符号,且该符号能够代表随意字符,即字符串2中存在通配符. e.g. 输入:abcdefghabef, a*f 输出:abcdef #include <iostream> #include <string> using namespace std; bool Match(const string &s1,const string &s2,string &result

含通配符的字符串匹配问题

题目: 给定两个字符串,求字符串2,在字符串1中的最先匹配结果.字符串2中 可以存在'*'符号,且该符号可以代表任意字符,即字符串2中存在通配符. 例如:输入:abcdefghabef,a*f 输出:abcdef #include<iostream> #include<string> using namespace std; int main() { int i=0,len=0,len1,len2,j=0,begin=0; string s,s1,s2,s3; getline(ci

【python cookbook】【字符串与文本】3.利用shell通配符做字符串匹配

问题:当工作在Linux shell下时,使用常见的通配符模式(即,*.py.Dat[0-9]*.csv等)来对文本做匹配 解决方案:fnmatch模块提供的两个函数fnmatch().fnmatchcase() #fnmatch()的匹配模式所采用的大小写区分规则和底层文件系统相同(根据操作系统的不同 而不同) #fnmatchcase()的匹配模式区分大小写 >>> from fnmatch import fnmatch,fnmatchcase >>> fnmatc

Python实用技法第22篇:利用Shell通配符做字符串匹配

1.需求 当工作在UNIX Shell下时,我们想使用常见的通配符模式(即:.py,Dat[0-9].csv等)来对文本做匹配. 2.解决方案 fnmatch模块提供了两个函数:fnmatch()和fnmatchcase(),可用来执行这样的匹配,使用起来非常简单. 实例: from fnmatch import fnmatch,fnmatchcase print(fnmatch('mark.txt','*.txt')) print(fnmatch('mark.txt','?ark.txt'))