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
Dynamic Programming Backtracking String
Solution in Java 1:
public class Solution {
public boolean isMatch(String s, String p) {
if(p.length()<=1){
if(s.length()==0&&p.length()==0) return true;
if(s.length()==1&&p.length()==1)
return p.charAt(0)=='.'||p.charAt(0)==s.charAt(0);
return false;
}
if(p.charAt(1)=='*'){
while(s.length()>0&&(p.charAt(0)=='.'||p.charAt(0)==s.charAt(0))){
if(isMatch(s, p.substring(2))) return true; //cant use isMatch(s.substring(1), p.substring(2)) here, for example "a" and "a*a"
s=s.substring(1);
}
return isMatch(s, p.substring(2));
}
else
return s.length()>0&&(p.charAt(0)=='.'||p.charAt(0)==s.charAt(0))&&isMatch(s.substring(1), p.substring(1));
}
}
Note:
reference from http://leetcode.com/2011/09/regular-expression-matching.html
Solution in Java 2: DP approach
public class Solution {
public boolean isMatch(String s, String p) {
int lenS = s.length();
int lenP = p.length();
boolean[][] opj = new boolean[lenS+1][lenP+1];
//opj[i][j] denotes if s[0...i-1] matches p[0...j-1]
//so opj[lenS][lenP] denotes if s[0...lenS-1] matches p[0...lenP-1]
opj[0][0] = true;
for(int i=1; i<=lenS; i++)
opj[i][0] = false;
for(int j=1; j<=lenP; j++){
opj[0][j] = j-2>=0&&opj[0][j-2]&&p.charAt(j-1)=='*';
}
for(int i=1; i<=lenS; i++){
for(int j=1; j<=lenP; j++){
if(p.charAt(j-1)!='*') //if p[j-1]!='*'
opj[i][j] = opj[i-1][j-1]&&(p.charAt(j-1)=='.'||p.charAt(j-1)==s.charAt(i-1));
else{ //if p[j-1]=='*', denote p ends with "x*"
opj[i][j] = //case 1: "x" repeates 0 times in s
opj[i][j-2]&&j-2>=0||
//case 2: "x" repeates exactly 1 times in s, can remove "*" in p
opj[i][j-1]||
//case 3: "x" repeates multiple times in s, so s is in the form of "x*x"
j-2>=0&&(p.charAt(j-2)=='.'||p.charAt(j-2)==s.charAt(i-1))&&opj[i-1][j];
}
}
}
return opj[lenS][lenP];
}
}