首页 > 代码库 > Regular Expression Matching

Regular Expression Matching

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).

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

解法1和2本质都一样,只不过解法2存储了局部结果,避免了重复处理一些字串,加快了计算的速度。
解法的关键思想就是提前判断下一个模式字符,从而分别处理下一个字符是‘*’以及非‘*’的情况; 需要自己看一下的是处理模式串中下一个字符是‘*‘的时候用的循环,用自己构造的一些输入用例来走几遍就可以理解了。


class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.  
        // 1
        /*
        if (s == NULL || p == NULL) return s == p;
        if (*p == ‘\0‘) return *s == *p;
        if (p[1] != ‘*‘) {
            return (*p == *s || (*p == ‘.‘ && *s != ‘\0‘)) && isMatch(s + 1, p + 1);
        }
        
        int offset = -1;
        do {
            ++offset;
            if (isMatch(s + offset, p + 2)) return true;
        } while (s[offset] == *p || (*p == ‘.‘ && s[offset] != ‘\0‘));
        
        return false;
        */
        
        // 2
        if (s == NULL || p == NULL) return s == p;
        if (*p == ‘\0‘) return *s == *p;
        
        int slen = strlen(s), plen = strlen(p);
        vector<vector<int>> mflag(slen + 1, vector<int>(plen + 1, -1));
        mflag[slen][plen] = 1;
        for (int i = 0; i < slen; ++i) {
            mflag[i][plen] = 0;
        }
        
        return isMatchHelper(s, p, mflag, 0, 0);
    }
    
private:
    bool isMatchHelper(const char *s, const char *p, vector<vector<int>> &flag, int spos, int ppos) {
        if (flag[spos][ppos] >= 0) {
            return flag[spos][ppos] == 1;
        }
        
        bool ret = false;
        if (p[ppos + 1] != ‘*‘) {
            ret = ((s[spos] == p[ppos] || (p[ppos] == ‘.‘ && s[spos] != ‘\0‘)) && isMatchHelper(s, p, flag, spos + 1, ppos + 1));
            flag[spos][ppos] = (ret ? 1 : 0);
            return ret;
        }
        
        int offset = -1;
        do {
            ++offset;
            ret = isMatchHelper(s, p, flag, spos + offset, ppos + 2);
            if (ret) {
                flag[spos][ppos] = 1;
                return ret;
            }
        } while (s[spos + offset] == p[ppos] || (p[ppos] == ‘.‘ && s[spos + offset] != ‘\0‘));
        
        flag[spos][ppos] = 0;
        return false;
    }
    
};


Regular Expression Matching