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
The algorithm of this problem is DFS
public class Solution {
public boolean isMatch(String s, String p) {
int slen = s.length();
int plen = p.length();
boolean isMatch = false;
if(plen == 0)
isMatch = (slen == 0)? true : false;
else{
StringBuffer first = new StringBuffer(p);
Stack<IndexChar> indcha = new Stack<IndexChar>();
Stack<StringBuffer> checked = new Stack<StringBuffer>();
//remove the leading '*'s
while(first.charAt(0) == '*'){
first = first.deleteCharAt(0);
--plen;
}
//remove all * and the preceding char
int i = 1;
for(; i < plen; ++i){
if(first.charAt(i) == '*'){
IndexChar next = new IndexChar(i - 1, first.charAt(i -1));
if(!indcha.empty()){
IndexChar in = indcha.pop();
if(!in.equal(next)){
indcha.push(in);
indcha.push(next);
}
else
indcha.push(in);
}
else
indcha.push(next);
first = first.delete(i - 1, i + 1);
i = i - 2;
plen = plen - 2;
}
}
if(isSame(s,first.toString()))
isMatch = true;
//dfs search
checked.push(first);
while(!isMatch && !indcha.empty()){
Stack<StringBuffer> sbuf = new Stack<StringBuffer>();
IndexChar inserted = indcha.pop();
while(!checked.empty() && !isMatch){
StringBuffer st = checked.pop();
int ind = inserted.index;
char c = inserted.cha;
int length = st.length();
while(length < slen + 1){
StringBuffer cst = new StringBuffer(st.toString());
if(isSame(s, cst.toString())){
isMatch = true;
break;
}
else{
int len = length - ind;
if(isSame(s.substring(slen - len, slen), cst.toString().substring(ind, length)))
sbuf.push(cst);
}
st.insert(ind, c);
++length;
}
}
checked = sbuf;
}
}
return isMatch;
}
public static boolean isSame(String s, String p){
int slen = s.length();
int plen = p.length();
boolean isSame = true;
if(slen != plen)
isSame = false;
else{
for(int i = 0; i < slen; ++i)
if(s.charAt(i) != p.charAt(i) && p.charAt(i) != '.'){
isSame = false;
break;
}
}
return isSame;
}
}
class IndexChar{
int index;
char cha;
IndexChar(int i, char c){
index = i;
cha = c;
}
boolean equal(IndexChar other){
return index == other.index && cha == other.cha;
}
}