题意:t组数据,给出两个字符串,对于每个字符串的每个子字符串通过"."隔开。有三个特殊作用的字符"?","*","!",求按照匹配规则,两个字符串是否匹配。
思路:一开始硬肝dp一直wa,所以由于这三个字符的特殊作用,我们应该简化一下三个字符,我们可以重新定义!:匹配一个,*作用不变,?:匹配一个或者不匹配。这样原来的*仍然是*,?变为!??,!变为!!*。这样对于dp[i][j]是否有解只需要看dp[i-1][j-1],dp[i][j-1],dp[i-1][j]其中几个的状态就行了。(dp[i][j],表示到第一个字符串的第i个字符串,第二个字符串的第j个子字符串为止,两字符串是否匹配)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define NUM 256
#define debug true
#define ll long long
#define lowbit(x) ((-x)&x)
#define ffor(i,d,u) for(int i=d;i<=u;++i)
#define _ffor(i,u,d) for(int i=u;i>=d;--i)
#define mst(array,Num) memset(array,Num,sizeof(array))
const int p = 1e9+7;
char a[NUM],b[NUM];
bool dp[NUM][NUM];
int linka[NUM],linkb[NUM];
int l1,l2,ls1,ls2;
string s1,s2;
template <typename T>
void read(T& x)
{
x=0;
char c;T t=1;
while(((c=getchar())<'0'||c>'9')&&c!='-');
if(c=='-'){t=-1;c=getchar();}
do(x*=10)+=(c-'0');while((c=getchar())>='0'&&c<='9');
x*=t;
}
template <typename T>
void write(T x)
{
int len=0;char c[21];
if(x<0)putchar('-'),x*=(-1);
do{++len;c[len]=(x%10)+'0';}while(x/=10);
_ffor(i,len,1)putchar(c[i]);
}
void tryya(const int& pos)//重新定义!:匹配一个,*不变,?:匹配一个或者不匹配
{
if(a[l1]=='*')
return ;
if(a[l1]=='!')
{
a[++l1]='!';
a[++l1]='*';
return ;
}
if(a[l1]=='?')
{
a[l1]='!';
a[++l1]='?';
a[++l1]='?';
return ;
}
linka[l1]=pos;
}
void tryyb(const int& pos)//重新定义!:匹配一个,*不变,?:匹配一个或者不匹配
{
if(b[l2]=='*')
return ;
if(b[l2]=='!')
{
b[++l2]='!';
b[++l2]='*';
return ;
}
if(b[l2]=='?')
{
b[l2]='!';
b[++l2]='?';
b[++l2]='?';
return ;
}
linkb[l2]=pos;
}
void solve()
{
int k1,k2;bool flag;
dp[0][0]=true;
ffor(i,1,l1)if(a[i]=='?'&&dp[i-1][0])dp[i][0]=true;
ffor(i,1,l2)if(b[i]=='?'&&dp[0][i-1])dp[0][i]=true;
ffor(i,1,l1)
ffor(j,1,l2)
{
flag=false;
if(a[i]=='*'||b[j]=='*')
{
if(a[i]=='*'&&(dp[i][j-1]||dp[i-1][j-1]))dp[i][j]=true;
if(b[j]=='*'&&(dp[i-1][j]||dp[i-1][j-1]))dp[i][j]=true;
flag=true;
}
if(a[i]=='!'||b[j]=='!')
{
if(dp[i-1][j-1])
dp[i][j]=true;
flag=true;
}
if(a[i]=='?'||b[j]=='?')
{
if(a[i]=='?'&&(dp[i-1][j-1]||dp[i-1][j]))dp[i][j]=true;
if(b[j]=='?'&&(dp[i-1][j-1]||dp[i][j-1]))dp[i][j]=true;
flag=true;
}
if(flag||!dp[i-1][j-1])continue;
k1=linka[i],k2=linkb[j];
flag=true;
while(k1<=ls1&&k2<=ls2&&s1[k1]!='.'&&s2[k2]!='.')
{
if(s1[k1]!=s2[k2])
{
flag=false;
break ;
}
++k1,++k2;
}
dp[i][j]=((k1>ls1||s1[k1]=='.')&&(k2>ls2||s2[k2]=='.')&&flag);
}
if(dp[l1][l2])
puts("YES");
else
puts("NO");
}
void AC()
{
int T;
read(T);
while(T--)
{
cin>>s1>>s2;
a[1]=s1[0];b[1]=s2[0];
l1=l2=1;
tryya(0);tryyb(0);
mst(dp,false);
ls1=s1.size()-1;
ffor(i,1,ls1)if(s1[i]=='.'){a[++l1]=s1[i+1];tryya(i+1);}
ls2=s2.size()-1;
ffor(i,1,ls2)if(s2[i]=='.'){b[++l2]=s2[i+1];tryyb(i+1);}
solve();
}
}
int main()
{
AC();
return 0;
}