【题目】
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
【思路】
该文借鉴了http://blog.csdn.net/hopeztm/article/details/7992253/中所提出的方法,
1、若当前p的下一个字符不为‘*’,则比较s和p的当前字符,若匹配,则s和p同时向后移动一个字符,否则,返回false;
2、若当前p的下一个字符为‘*’,则在s和p的当前字符可以匹配的情况下进入循环:
a) 、p向后移动两个字符后与当前s是否匹配,若匹配,退出循环,返回true,否则,进入b);
b) 、s向后移动一个字符,重新开始循环;
若s和p的当前字符不匹配,则直接将p向后移动两个字符,返回新字符串p与s的匹配结果;
【解疑】
Q:s和p的当前字符怎样才算匹配?
A:第一种情况——字符相同;
第二种情况——p当前字符为‘.’,且s不为空;
Q:第2步的循环中,步骤a)和步骤b)的顺序是否可以颠倒?
A:不可以,举例说明s = "daa"以及p="da*a"的匹配过程:
正确过程:p先向后移动两个字符 | 错误过程:s先向后移动一个字符 |
【Java代码】
public class Solution_10_regular_expression_matching {
public static boolean isMatch(String s, String p){
if(p.length() == 0) return s.length() == 0;
if(p.length() == 1 || p.charAt(1) != '*'){
if((s.length() != 0 && s.charAt(0) == p.charAt(0)) || (p.charAt(0) == '.' && s.length() != 0))
return isMatch(s.substring(1),p.substring(1));
else
return false;
}else{
while((s.length() != 0 && s.charAt(0) == p.charAt(0)) || (p.charAt(0) == '.' && s.length() != 0)){
boolean current = isMatch(s,p.substring(2));
if(current)
return current;
else
s = s.substring(1);
}
return isMatch(s,p.substring(2));
}
}
}