鏈接
https://leetcode-cn.com/problems/regular-expression-matching/
題意
給你一個 匹配串 s 和一個 模式串 p,實現一個支持 ‘.’ 和 ‘*’ 的正則表達式匹配。
’.’ 匹配任意單個字符
’*’ 匹配零個或多個前面的那一個元素
思路
動態規劃。
表示 和 是否能匹配。自底向上計算。
因爲有 ‘*’,’*’ 比較麻煩,它會出現在當前匹配的字符的後面,匹配零個或任意多個當前元素。也就是說可以有 任意多個 當前字符,也可以 沒有(忽略)。
分兩種情況討論:
- 當前字符後面是 ‘*’ 的情況,
if(j+1 < p.size() && p[j+1] == '*')
,可以有兩種選擇,忽略 模式串p 的這個字符(0個),或者在匹配當前字符的情況下 模式串p不動 繼續匹配剩下的 匹配串s(任意多個)。
- 沒有 ‘*’ 的情況,直接匹配當前字符和剩下的串即可:
PS: 初始化時需要注意
j == p.size()
相當於 模式串 p 爲空,只要 匹配串 s 不爲空,一定匹配失敗。i== s.size()
相當於 匹配串 s 爲空,這時 模式串p 可以不爲空而匹配成功,eg:s = "", p = "a*"
。- 模式串p 和 匹配串s 都爲 空 是匹配成功的。
AC代碼
class Solution {
public:
bool isMatch(string s, string p) {
bool dp[s.size()+1][p.size()+1];
for(int i = 0; i < s.size(); ++i) dp[i][p.size()] = 0; // j == p.size()相當於 模式串 p 爲空,只要 匹配串 s 不爲空,一定匹配失敗。
dp[s.size()][p.size()] = 1; // 模式串 和 匹配串 都爲 空 可以匹配成功
for(int i = s.size(); i >= 0; --i) { // i 從 s.size() 開始是因爲 匹配串s 爲空,模式串p 可以不爲空而匹配成功,eg:s = "", p = "a*";
for(int j = p.size()-1; j >= 0; --j) {
bool first_match = i < s.size() && (s[i] == p[j] || p[j] == '.');
if(j+1 < p.size() && p[j+1] == '*') {
dp[i][j] = dp[i][j+2] || (first_match && dp[i+1][j]);
}
else {
dp[i][j] = first_match && dp[i+1][j+1];
}
}
}
return dp[0][0];
}
};