Question

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 <!--more-->

Dynamic Programming

f(i,j) represents whether the first i letters of string s can be matched by the first j letters of regular expression p(0 means no and 1 means yes). Therefore, the recursion formula can be written as:
  (1) if p[i] == '.', f(i,j) = f(i-1,j-1)
  (2) if p[i] == '*', f(i,j) = f(i,j-2) or { s[i] match p[j-1] and f(i-1,j) }
  (3) if p[i] != '.' and p[i] != '*',
    f(i,j) = f(i-1,j-1), when s[i] == p[j]
    f(i,j) = 0, when s[i] != p[j]

bool isMatch(char * s,char * p)
{
    int lens = strlen(s--), lenp = strlen(p--);
    bool f[lens + 1][lenp + 1];
    
    memset(f,0,sizeof(f));
    f[0][0] = 1;
    for(int j = 1;j <= lenp;++j)
        f[0][j] = p[j] == '*' && f[0][j - 2];//init

    for(int j = 1;j <= lenp;++j)
    for(int i = 1;i <= lens;++i)
        if(p[j] == '*')
            f[i][j] = f[i][j - 2] || (s[i] == p[j - 1] || p[j - 1] == '.') && f[i - 1][j];
        else if(s[i] == p[j] || p[j] == '.') 
            f[i][j] = f[i-1][j-1];
    return f[lens][lenp];
}
  • Time Complexity: O(n^2)
  • Space Complexity: O(n^2)

Finding law

By observing the samples above, we can find the law and solve it directly

bool isMatch(char *s, char *p)
{
    if (*s==0 && *p==0) return true;
    if (*p==0 || (*s==0 && *(p+1)!='*') ) return false;

    if (*(p + 1) != '*')
        return (*p == *s || *p == '.') ? isMatch(s + 1, p + 1) : false;

    do if (isMatch(s, p + 2)) return true;
    while (*s && (*(s++) == *p || *p == '.'));
    return false;
}
  • Time Complexity: O(n)
  • Space Complexity: O(1)