Leetcode: 10. Regular Expression Matching

Description

Implement regular expression matching with support for '.' and '*'.算法

Example

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

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

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true

思路

  • 匹配問題
  • '.' 匹配任意單個字符,'*' 匹配前面的字符0次或屢次
  • 由於須要考慮前面的字符,因此從後往前匹配。
  • 考慮 '*'時的特殊狀況,若是 ' * '前面的字符和要匹配的同樣,則分兩張狀況,即匹配0次或屢次
  • 若是不同,則要匹配的不變,而後跳到*字符前面的前面。
  • 沒有說清楚,看代碼吧

代碼

class Solution {
public:
    bool isMatch(string s, string p) {
        int slen = s.size();
        int plen = p.size();
        
        return matchFunc(s, slen - 1, p, plen - 1);
    }
    
    bool matchFunc(string& s, int i, string &p, int j){
        if(i < 0 && j < 0) return true;
        if(i < 0 ) return p[j] == '*' ? matchFunc(s, i, p, j - 2) : false;
        if(j < 0) return false;
        
        if(s[i] == p[j] || p[j] == '.'){
            return matchFunc(s, i - 1, p, j - 1);
        }
        else if(p[j] == '*'){ 
            bool res = false;
            //特殊狀況
            if(j - 1 >= 0){
                if(p[j - 1] == '.' || p[j - 1] == s[i])
                    res =  matchFunc(s, i - 1, p, j) || matchFunc(s, i - 1, p, j - 2);
            }
            
            return res || matchFunc(s, i, p, j - 2);
        }
        
        return false;
    }
};

動態規劃

  • 再討論區裏面還看到了一種動態規劃的算法。在這裏也做一個介紹,不得不感嘆一句,大佬仍是多呀。express

  • dp[i][j] 表示s[0..i)和p[0..j)的匹配結果,若爲ture,則匹配,不然不匹配學習

  • 則一共有如下狀態:prototype

    • dp[i][j] = dp[i - 1][j - 1],if p[j - 1] != '*' && (s[i - 1] == p[j - 1] || p[j - 1] == '.'),注意下標的控制,dp[i][j]的下標是長度,而p[j-1]對應於dp[i][j]
    • dp[i][j] = dp[i][j - 2], if p[j - 1] == '*', 且匹配0次
    • dp[i][j] = dp[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.'),此時p[j - 1] == '*' 且至少匹配一次
  • 代碼以下:code

    class Solution {
    public:
        bool isMatch(string s, string p) {
            int slen = s.size();
            int plen = p.size();
        
            vector<vector<bool>> dp(slen + 1, vector<bool>(plen + 1, false));
            dp[0][0] = true;
            for(int i = 0; i <= slen; ++i){
                for(int j = 1; j <= plen; ++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[slen][plen];
        }
    };

總結

  • 遞歸每每能夠改善的
  • 向大佬學習!
相關文章
相關標籤/搜索