📅  最后修改于: 2023-12-03 15:42:20.343000             🧑  作者: Mango
本题为 Sudo GATE 2020 Mock I(2019 年 12 月 27 日)中的问题 23。
题目描述如下:
给定一个字符串 s 和一个模式串 p,实现一个函数来判断 s 是否匹配 p。
在匹配中,'?' 可以匹配任何单个字符。'*' 可以匹配任意字符串(包括空字符串)。
示例:
输入:
s = "adcefg" p = "a?c"
输出:
true
输入:
s = "aa" p = "a"
输出:
false
输入:
s = "aa" p = "*"
输出:
true
可以使用动态规划来解决这个问题。
我们定义一个二维数组 dp,其中 dp[i][j] 表示 s 的前 i 个字符和 p 的前 j 个字符是否能够匹配。
初始化 dp[0][0] = true,表示空串和空模式串能够匹配。然后我们需要考虑当其中一个字符串为空串时的情况。当 s 为空串时,如果 p 的前 j 个字符都是 '*',那么 dp[0][j] = true;当 p 为空串时,只有当 s 也为空串时,dp[0][0] = true,其它 dp[0][j] = false。
接着,我们考虑转移方程。如果 s 的第 i 个字符和 p 的第 j 个字符能够匹配(即 s[i-1] == p[j-1] 或 p[j-1] == '?'),那么 dp[i][j] = dp[i-1][j-1],否则如果 p[j-1] == '*',那么 dp[i][j] 可以从 dp[i-1][j] 或者 dp[i][j-1] 转移而来。
最终,dp[s.length()][p.length()] 即为题目所求的结果。
public boolean isMatch(String s, String p) {
int m = s.length(), n = p.length();
boolean[][] dp = new boolean[m + 1][n + 1];
dp[0][0] = true;
for (int i = 1; i <= n; i++) {
if (p.charAt(i - 1) == '*') {
dp[0][i] = true;
} else {
break;
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?') {
dp[i][j] = dp[i - 1][j - 1];
} else if (p.charAt(j - 1) == '*') {
dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
}
}
}
return dp[m][n];
}
本题主要考察了字符串匹配和动态规划的基本思想,需要我们在实际应用中能够熟练掌握。通过题目的解法过程,我们可以更好地理解动态规划的思路,并且能够写出符合要求的代码。