剣指offer——正規表現マッチング(c++)
16666 ワード
タイトルの説明
考えが再帰する.
モードの次の文字が
構想動的計画
2 D DP配列を定義し、dp[i][j]はs[0,i)とp[0,j)がmatchであるか否かを表し、以下の3つのケース(以下、Leetcodeより抜粋)がある.
'.'
および'*'
を含む正規表現を一致させるための関数を実装してください.パターン内の文字'.'
は任意の文字を表し、'*'
はその前の文字が任意の回数(0回を含む)現れることを表す.本題では、マッチングとは、文字列のすべての文字がモード全体に一致することを意味します.例えば、文字列「aaa」は、パターン「a.a」および「ab*ac*a」と一致するが、「aa.a」および「ab*a」と一致しない.サンプル :
s="aa"
p="a*"
:true
考えが再帰する.
モードの次の文字が
'*'
の場合、現在の文字が一致する場合、文字列が1ビット後方に移動するか、モードが2ビット後方に移動するかの2つのケースに分けられます.逆に、現在の文字が一致しない場合、モードは2ビット後方に移動します.モードの次の文字が'*'
でない場合、現在の文字が一致している場合、またはモードが'.'
である場合、次の文字を一致させ続け、そうでない場合falseを返します.class Solution {
public:
bool isMatch(string s, string p) {
if(p.empty())
return s.empty();
return match(s, p, 0, 0);
}
bool match(string s, string p, int i, int j){
// , , true
if(i == s.size() && j == p.size())
return true;
//p , s ,
if(i != s.size() && j == p.size())
return false;
if(p[j+1] == '*'){
if(s[i] == p[j] || (i < s.size() && p[j] == '.'))
return match(s, p, i+1, j) || match(s, p, i, j+2);
else
return match(s, p, i, j+2);
}
else{
if(s[i] == p[j] || (i < s.size() && p[j] == '.'))
return match(s, p, i+1, j+1);
else
return false;
}
}
};
構想動的計画
2 D DP配列を定義し、dp[i][j]はs[0,i)とp[0,j)がmatchであるか否かを表し、以下の3つのケース(以下、Leetcodeより抜粋)がある.
P[i][j] = P[i - 1][j - 1]
, if p[j - 1] != '*'&& (s[i - 1] == p[j - 1] || p[j - 1] == '.')
; P[i][j] = P[i][j - 2]
, if p[j - 1] == '*'
and the pattern repeats for 0 times; P[i][j] = P[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.')
, if p[j - 1] == '*'
and the pattern repeats for at least 1 times. class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size(), n = p.size();
vector<vector<bool> > dp(m + 1, vector<bool>(n + 1, false));
dp[0][0] = true;
for (int i = 0; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (j > 1 && p[j - 1] == '*') {
dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);
} else {
dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
}
}
}
return dp[m][n];
}
};