leetcode——Regular Expression Matching

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

原題如上算法

leetdcode給這道題打上的標記是有DP,雖然DP也可以作,可是我真的不認爲DP是一個很直觀的方法。好吧,我是普通青年,這題最難的地方在於backtracking,回溯,然而我卡在了這裏。spa

對於匹配,一個很直觀的方法就是貪心,儘量的取匹配更多的字符。可是因爲*這個字符可能匹配0個,1個或者多個,致使到底在匹配多少次上貪心算法並不能很好的控制。若是解決「*」這個字符的匹配難題呢?prototype

咱們仍是以從頭至尾的方式來匹配字符,對於‘*’的處理,咱們是按照以下的:
code

  1. If the next character of p is NOT ‘*’, then it must match the current character of s. Continue pattern matching with the next character of both s and p.遞歸

  2. If the next character of p is ‘*’, then we do a brute force exhaustive matching of 0, 1, or more repeats of current character of p… Until we could not match any more characters.element

若是下一個字符是'*',那麼咱們應該對匹配0次,1次,屢次作一次暴力求解,考慮全部的狀況。每一種狀況,以一個遞歸的方式去解決。input

既然是遞歸,那麼就要好好地考慮base。我認爲這個遞歸的base應該是待匹配串和匹配串都已經掃描完。string

int isMatch(char* s, char* p)
{
    assert(s && p); //s and p are null
    if (*p == '\0')
    {
        return *s == '\0';
    }
    if (*(p+1) != '*')  //next character is not '*'
    {
        assert(*p != '*');
        if ((*p == *s) || (*p == '.' && *s != '\0'))
        {
            return isMatch(s+1, p+1);
        }else{
            return 0;
        }
    }else{ //next character is '*', match 0, 1, 2,... times
        while ((*p == *s) || (*p == '.' && *s != '\0'))
        {
            if (isMatch(s, p+2))
            {
                return 1;
            }
            s++;
        }
        return isMatch(s, p+2);
    }
}
相關文章
相關標籤/搜索