10. 正则表达式匹配
首先定义:
-
设s为原串,p为匹配符串
-
dp[i] [j] 代表,s串的1到i个字符是否与p串的1到j个字符匹配
于是我们在回到定义:
若 s[i] == p[j] || p[j]=='.' ,那么显然dp[i+1] [j+1] =dp[i] [j];
如果p[j]=='*',那么我们考虑以下三种情况
- 此时匹配*表示空,则dp[i+1] [j+1] = dp[i+1] [j-1]
- 此时匹配*表示1,则dp[i+1] [j+1] = dp[i+1] [j]
- 此时匹配*表示多个,则必须满足先匹配一个的情况即: s[i] == p[j-1] || p[j-1]=='.'
- 此时,dp[i+1] [j+1] = dp[i] [j+1]
但此时还需要考虑初始条件:
显然按照定义dp[0] [0] =true
因为dp[1~k] [0]不可能为真,不必再次初始化
而dp[0] [1~k]是可能为真的,于是需要初始化,如果p[j]=='*' 那么dp[0] [j+1] =dp[0] [j-1]
代码如下:
public boolean isMatch(String s, String p) {
boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
dp[0][0] = true;
for (int j = 0; j < p.length(); j++) {
if (p.charAt(j) == '*' && j > 0) dp[0][j+1] = dp[0][j - -1];
}
for (int i = 0; i < s.length(); i++) {
for (int j = 0; j < p.length(); j++) {
if (p.charAt(j) == '.' || p.charAt(j) == s.charAt(i)) {
dp[i + 1][j + 1] = dp[i][j];
} else if (p.charAt(j) == '*') {
if (j > 0) dp[i + 1][j + 1] |= dp[i + 1][j - 1];
dp[i + 1][j + 1] |= dp[i + 1][j];
if (j > 0 && (p.charAt(j - 1) == '.' || p.charAt(j - 1) == s.charAt(i)))
dp[i + 1][j + 1] |= dp[i][j+1];
}
}
}
return dp[s.length()][p.length()];
}