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
这道题明显运用递归算法,但是想编码还是要特别分析题目含义,找到递归公式。
如果P[j+1]!='*',S[i] == P[j]=>匹配下一位(i+1, j+1),S[i]!=P[j]=>匹配失败;
如果P[j+1]=='*',S[i]==P[j]=>匹配下一位(i+1, j+2)或者(i, j+2),S[i]!=P[j]=>匹配下一位(i,j+2)。
匹配成功的条件为S[i]=='\0' && P[j]=='\0'。
当用java去实现发现没有用c中指针那么方便。S[i]=='\0' 判断改用S.length()关系判断。还需要单独考虑长度为奇数情况。java实现没有C那么快,递归去求字符串的子串非常消耗时间。
public class Solution {
public boolean isMatch(String s, String p) {
if (p.length() ==0) {
return s.length()==0;
}
//长度减2,如果开始为奇数则需要考虑到长度为1情况
if (p.length() == 1)
return (s.length() == 1)
&& (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.');
if (p.charAt( 1) == '*') {
while (s.length()>0
&& (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.')) {
if (isMatch(s, p.substring(2)))
return true;
s = s.substring(1);
}
return isMatch(s, p.substring(2));
} else {
if (s.length()>0 && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.')){
return isMatch(s.substring(1), p.substring(1));
}
}
return false;
}
}
C代码则比较清晰明了一些:
class Solution {
public:
bool isMatch(const char *s, const char *p) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if (*p == '\0') {
return *s == '\0';
}
if (*(p + 1) == '*') {
while (*s != '\0' && (*s == *p || *p == '.')) {
if (isMatch(s, p + 2)) {
return true;
}
s++;
}
return isMatch(s, p + 2);
}
else {
if (*s != '\0' && (*s == *p || *p == '.')) {
return isMatch(s + 1, p + 1);
}
}
return false;
}
};
参考:http://blog.youkuaiyun.com/pickless/article/details/9043389 感谢。