这题较难。使用递归DFS容易导致超时,使用DP有许多需要注意的地方。该题的牛客网题解大多数没有考虑全面,这里给出我的解法。
1. *的匹配需要注意边界情况。
2. *和?只能匹配字母和数字。
3. 大小写不敏感
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
bool dp[101][101];
int main()
{
string a, b;
while (cin >> a >> b)
{
// 全部转为小写
transform(a.begin(), a.end(), a.begin(), ::tolower);
transform(b.begin(), b.end(), b.begin(), ::tolower);
// 处理边界情况,a和b在最前面加上一个字符'x',表示字符串为空的情况
a = 'x' + a;
b = 'x' + b;
dp[0][0] = true; // 两边都为空,则为true
// 一个*或者多个*,可以匹配空字符
for (int i = 1; i < a.length(); ++i)
dp[i][0] = dp[i - 1][0] && (a[i] == '*');
for (int i = 1; i < a.length(); ++i)
{
for (int j = 1; j < b.length(); ++j)
{
if (a[i] == '*')
{
if (isalnum(b[j])) // 如果b[j]是数字或者字母
dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; // *可以不参与匹配,也可以匹配它
else
dp[i][j] = dp[i - 1][j]; // 否则,*只能不参与匹配
}
else if (a[i] == '?' && isalnum(b[j])) // ?只能参与匹配字母或数字
dp[i][j] = dp[i - 1][j - 1];
else if (a[i] == b[j]) // 如果两个字符相等,那么匹配他们
dp[i][j] = dp[i - 1][j - 1];
else // 两个字符不相等,那么只能false了
dp[i][j] = false;
}
}
if (dp[a.length() - 1][b.length() - 1])
cout << "true" << endl;
else
cout << "false" << endl;
}
return 0;
}
如果对你有帮助,记得点个赞哦~