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
思想:
可以想象成走二维格子的问题,从左上角开始找,找符合要求的格子,上一个格子影响下一个格子
1, If p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1];//符合要求则走斜线
2, If p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];//符合要求走斜线
3, If p.charAt(j) == '*':
存在两种可能:
1 if p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2] //这种情况下,不符合条件
2 if p.charAt(j-1) == s.charAt(i) or p.charAt(j-1) == '.':
dp[i][j] = dp[i-1][j] //这种情况下存在多个
or dp[i][j] = dp[i][j-1] // 这种情况下存在一个
or dp[i][j] = dp[i][j-2] // 这种情况下不符合条件
代码如下:
public class RegularExpressionMatching {
public boolean isMatching(String s,String p){
if(s==null || p==null){
return false;
}
boolean[][] dp = new boolean[s.length()+1][p.length()+1];
dp[0][0] = true;
for(int i=0;i<p.length();i++){
if(p.charAt(i) == '*' && dp[0][i-1]){
dp[0][i+1]=true;
}
}
for(int i=0;i<s.length();i++){
for(int j=0;j<p.length();j++){
if(p.charAt(j) == '.' || p.charAt(j) == s.charAt(i)){
dp[i+1][j+1] = dp[i][j];
}
if(p.charAt(j) == '*'){
if(p.charAt(j-1) != s.charAt(i) && p.charAt(j-1) != '.'){
dp[i+1][j+1] = dp[i+1][j-1];
}else{
dp[i+1][j+1] = (dp[i+1][j] || dp[i][j+1] || dp[i+1][j-1]);
}
}
}
}
return dp[s.length()][p.length()];
}
}