题目描述
题解
感觉这道题刚开始令我迷惑的是一个*可能匹配多个字符,这样的话看起来没法搞啊。
实际上不用想那么多。只需要考虑从哪里转移就可以了。
f(i,j)表示第一个串的前i个字符能否匹配第二个串的前j个字符。那么可以进行分类讨论:
①如果s1[i]=’?’或者s1[i]=s2[j]的话,f(i,j)可以从f(i-1,j-1)转移过来。
②如果s1[i]=
∗
<script type="math/tex" id="MathJax-Element-1">*</script>的话,又有几种情况。假设*代表的是一个字符,那么同样可以从f(i-1,j-1)转移过来。假设代表的是空字符,那么可以从f(i-1,j)转移过来。假设代表的是很多字符,那么可以从f(i,j-1)转移过来。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char s1[1005],s2[1005];
int l1,l2,f[1005][1005];
int main()
{
gets(s1);l1=strlen(s1);
gets(s2);l2=strlen(s2);
for (int i=l1;i>=1;--i) s1[i]=s1[i-1];
for (int i=l2;i>=1;--i) s2[i]=s2[i-1];
for (int i=1;i<=l1;++i)
if (s1[i]=='*') f[i][0]=true;
else break;
f[0][0]=true;
for (int i=1;i<=l1;++i)
for (int j=1;j<=l2;++j)
{
if (s1[i]=='?'||s1[i]==s2[j])
f[i][j]|=f[i-1][j-1];
else if (s1[i]=='*')
f[i][j]|=f[i-1][i-1]|f[i-1][j]|f[i][j-1];
}
if (f[l1][l2]) puts("matched");
else puts("not matched");
}