Regular Expression Matching

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.

總結下問題:簡易的正則表達式匹配,如果s爲空,p也爲空,那麼匹配結果爲true;如果s爲"a",p爲"*",那麼匹配結果爲false;s只能是[a-z]的元素組成;p只能是[a-z.*]的元素組成.

思路:有兩種思路,遞歸和動態規劃。遞歸很好理解,網上的答案也是正確的。但是動態規劃的求解代碼,網上卻有很多的錯誤答案(官方還能運行通過!),這個會在後面驗證說明。

一,遞歸:考察p模式,@1 如果p爲空,那麼結果取決於s是否爲空,s爲空返回true,不爲空返回false.                                                                                   @2 如果p只有一個字符,那麼匹配結果取決於(s.size() ==1) && (s[0] == p[0] || p[0] == '.' )                                                                 @3 除了上述情況,那麼p至少有2個字符;對p的p[1]判斷,如果p[1]是非'*'字符,那麼結果取決於 s.empty() || (s[0] == p[0] || p[0] == '.' )  &&  isMatch(s.substr(1),p.substr(1))。 如果p[1]是'*'號,那麼判斷*號重複前面字符0次,1次,2次...是否匹配,一旦匹配返回true,否則每次判斷都縮小s的範圍,確保能循環終止。

二,動態規劃:參考官網上solution的jianchao-li的帖子,

  1. P[i][j] = P[i - 1][j - 1], if p[j - 1] != '*' && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
  2. P[i][j] = P[i][j - 2], if p[j - 1] == '*' and the pattern repeats for 0 times;
  3. 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.

這個思路夠清晰了,但是貼出來的代碼卻是錯誤的,如果s="",p="*",程序立馬崩潰!但官網上還是能運行通過。

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.length(), n = p.length(); 
        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 (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];
    }
};

附加遞歸代碼:

附加動態規劃代碼:

附加測試用例:

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章