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
大意是实现一个简单的正则匹配,'.'号表示一个字符,a*表示0到n个a,.*同理,0到多个
比较典型的动态规划问题,公式总结为
isMatch(s(0,m),p(0,n)) = isMatch(s(0,m-1),p(0,n-2)) || isMatch(s(0,m-1),p(0,n)) || isMatch(s(0,m),p(0,n-2)),即三种情况
如第一种:
isMatch("abc","a*bc")
= isMatch("bc","bc")
自己AC的代码:
public boolean isMatch(String s, String p) {
//结束调用的判断,s,p有一个为空
if((s==null||s.equals(""))&&(p==null||p.equals("")))
return true;
if(s==null||s.equals("")){
if(p==null)
return true;
else if(!(p.length()>1 && p.charAt(1)=='*')){
return false;
}
else
return isMatch(null,p.substring(2));
}
if(p==null||p.equals(""))
return false;
//果然还是要先把p剪枝,不然a*a*a*a*a*a*a*a*a*a*c这种溢出了
int i=0,j=2;
while(j+1<p.length()){
while(j+1<p.length() && p.charAt(i) == p.charAt(j) && p.charAt(i+1)=='*' && p.charAt(j+1)=='*'){
j+=2;
}
p=p.substring(0,i+2)+p.substring(j);
i+=2;
j=i+2;
}
//动态规划,s,p都已经不为空了
//p开头是.
if(p.startsWith(".")){
if(p.length()<2 || p.charAt(1)!='*')
return isMatch(s.substring(1),p.substring(1));
else if(p.length()>1 && p.charAt(1)=='*'){//.*情况
return isMatch(s.substring(1),p.substring(2)) || isMatch(s.substring(1),p) || isMatch(s,p.substring(2));//.*可能消掉可能不消,s的a也是
}
}
else if(p.length()>1&&p.charAt(1)=='*'){//p开头是a*
if(p.charAt(0)!=s.charAt(0))//ab不等时只能去掉p
return isMatch(s,p.substring(2));
else
return isMatch(s.substring(1),p.substring(2)) || isMatch(s.substring(1),p) || isMatch(s,p.substring(2));//a*可能消掉可能不消
}
else{//p开头是a
if(s.charAt(0)!=p.charAt(0))
return false;
else return isMatch(s.substring(1),p.substring(1));
}
return true;
}