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

Analysis

Back tracking,这样可以保证当前不match可以返回继续试别的match方式。

Recursion cases:

  1. 如果p的下一个char不是'*',当前p和s的char必须match。如果match,继续比较p的下一个和s的以一个char。
  2. 如果p的下一个char是'*',试着用0,1或者更多的p当前指向的char来match s,直到不能match为止。

Code

public class Solution {
    public boolean isMatch(String s, String p) {
        //base case when s==p==""
        if (p.isEmpty()) {
            return s.isEmpty();
        }

        if (p.length() == 1 || p.charAt(1) != '*') {
            if (s.isEmpty() || (p.charAt(0) != '.' && p.charAt(0) != s.charAt(0))) {
                return false;
            } else {
                return isMatch(s.substring(1), p.substring(1));
            }
        }

        //P.length() >=2
        while (!s.isEmpty() && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.')) {  
            if (isMatch(s, p.substring(2))) { 
                return true;                     
            }                                    
            s = s.substring(1);
        }

        return isMatch(s, p.substring(2));
    }
}

Note

Difference between string==null and string==""

  • string.isEmpty() returns true only if string.length()==0, which means this string is "", not null.
  • This question is hard, need to rewrite sometime.

Reference