LeetCode Regular Expression Matching

class Solution {

#define SINGLE 1

#define MULTIP 2

public:

    bool isMatch(const char *s, const char *p) {

        if (s == NULL || p == NULL) return true;

        

        vector<pair<char, int> > pattern;

        

        int     pos = 0;

        char     ch = '\0';

        

        while ((ch = p[pos++]) != '\0') {

            if (ch == '*') {

                pattern.back().second = MULTIP;

                continue;

            }

            pattern.push_back(make_pair(ch, SINGLE));

        }

        

        return isMatch(s, 0, pattern, 0);

    }

    

    bool isMatch(const char *s, int pos, vector<pair<char, int> > &pattern, int ppos) {

        if (ppos == pattern.size()) {

            return s[pos] == '\0';

        }

        int i = pos;

        pair<char, int> &p = pattern[ppos];



        int     offset = (p.second == SINGLE) ? 0 : -1;

        char     ch = '\0';

        while (offset < 0 || (ch = s[pos + offset]) != '\0') {

            if (offset >= 0 && !cmp(ch, p.first)) {

                return false;

            }

            if (isMatch(s, pos + offset + 1, pattern, ppos + 1)) {

                return true;

            }

            if (p.second == SINGLE) break;

            offset++;

        }

        return false;

    }

    

    bool cmp(const char a, const char b) {

        if (a == '.' || b == '.') return true;

        return a == b;

    }

};

暴力法, 216ms,

 

 

改写为记忆搜索,这里假设字符串和模式字符串的长度都不超过unsigned short 范围(6w+), 84ms

class Solution {

#define SINGLE 1

#define MULTIP 2

private:

    unordered_map<unsigned int, bool> memo;

public:

    bool isMatch(const char *s, const char *p) {

        if (s == NULL || p == NULL) return true;

        memo.clear();

        

        vector<pair<char, int> > pattern;

        

        int     pos = 0;

        char     ch = '\0';

        

        while ((ch = p[pos++]) != '\0') {

            if (ch == '*') {

                pattern.back().second = MULTIP;

                continue;

            }

            pattern.push_back(make_pair(ch, SINGLE));

        }

        

        return isMatch(s, 0, pattern, 0);

    }

    

    bool isMatch(const char *s, int pos, vector<pair<char, int> > &pattern, int ppos) {

        unsigned int id = (pos << 16) | ppos;

        

        unordered_map<unsigned int, bool>::iterator iter = memo.find(id);

        if (memo.find(id) != memo.end()) return iter->second;

        

        bool res = false;

        

        if (ppos == pattern.size()) {

            res = s[pos] == '\0';

            memo.insert(make_pair(id, res));

            return res;

        }

        int i = pos;

        pair<char, int> &p = pattern[ppos];



        int     offset = (p.second == SINGLE) ? 0 : -1;

        char     ch = '\0';

        while (offset < 0 || (ch = s[pos + offset]) != '\0') {

            if (offset >= 0 && !cmp(ch, p.first)) {

                res = false;

                break;

            }

            if (isMatch(s, pos + offset + 1, pattern, ppos + 1)) {

                res = true;

                break;

            }

            if (p.second == SINGLE) break;

            offset++;

        }

        memo.insert(make_pair(id, res));

        return res;

    }

    

    bool cmp(const char a, const char b) {

        if (a == '.' || b == '.') return true;

        return a == b;

    }

};

 

第二轮:

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

看到这样的题真有点写不下去,还是找了一发资料:

class Solution {

public:

    bool isMatch(const char *s, const char *p) {

        if (s == NULL || p == NULL) {

            return false;

        }

        if (*p == '\0') {

            return *s == '\0';

        }

        

        if (*(p+1) != '*') {

            return (*p == *s || (*p == '.' && *s != '\0')) && isMatch(s + 1, p + 1);

        }

        

        char curpat = *p;

        const char* sp = s;

        

        while (*sp == curpat || (curpat == '.' && *sp != '\0')) {

            if (isMatch(sp, p + 2)) {

                return true;

            }

            sp++;

        }

        return isMatch(sp, p + 2);

    }

};

 在discuss里找到一个dp解法:

class Solution {

public:

    bool isMatch(const char *s, const char *p) {

        const int slen = strlen(s);

        const int plen = strlen(p);

        vector<vector<bool> > dp(slen+1, vector<bool>(plen+1, false));

        

        

        // when src string is empty, pattern string should be in form of

        // a*b*c*...

        for (int i=2; i<=plen; i+=2) {

            if (p[i-1] == '*') {

                dp[0][i] = true;

            } else {

                break;

            }

        }

        dp[0][0] = true;

        

        for (int i=1; i<=slen; i++) {

            for (int j=1; j<=plen; j++) {

                if (s[i-1] == p[j-1] || p[j-1] == '.') {

                    dp[i][j] = dp[i-1][j-1];

                    continue;

                }   

                if (p[j-1] == '*') {

                    if (p[j-2] == s[i-1] || p[j-2] == '.') {

                        dp[i][j] = dp[i-1][j] || dp[i][j-2];

                    } else {

                        dp[i][j] = dp[i][j-2];

                    }

                }

            }

        }

        return dp[slen][plen];

    }

};

  

你可能感兴趣的:(LeetCode Regular Expression Matching)