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
Java:
这题有点难 但CodeGanker说面试出现频率不低,那还是要掌握
CodeGanker : http://blog.csdn.net/linhuanmars/article/details/21145563
下一个字符是*要跳过两个
public boolean isMatch(String s, String p) {
return helper(s,p,0,0);
}
private boolean helper(String s, String p, int i, int j)
{
if(j==p.length()) //pattern已经用光 如果s也用光说明匹配
return i==s.length();
//j+1!=*
if(j==p.length()-1 || p.charAt(j+1)!='*') // 如果pattern的j已经走到最后一个字符或者j+1后面不是*</span>
{
if(i==s.length()|| s.charAt(i)!=p.charAt(j) && p.charAt(j)!='.') //s已经走完说明不匹配
return false;
else
return helper(s,p,i+1,j+1);
}
//p.charAt(j+1)=='*' 且匹配
while(i<s.length() && (p.charAt(j)=='.' || s.charAt(i)==p.charAt(j)))
{
if(helper(s,p,i,j+2))
return true;
i++;
}
return helper(s,p,i,j+2);
}
其他:
1. http://zhongyinzhang.wordpress.com/2014/03/14/regular-expression-matching/
这个最好懂
public class Solution {
public boolean isMatch(String s, String p) {
assert(p!=null && (p.length()==0 || p.charAt(0)!='*'));
if(p.length()==0)
return s.length()==0;
//p.length == 1 is a special case
//Second character of p is not '*'
if(p.length()==1 || p.charAt(1)!='*'){
// if first character of p is not '.' and p.charAt(0) != s.charAt(0) return false
// else keep matching
if(s.length()<1 || (p.charAt(0)!='.' && p.charAt(0)!=s.charAt(0)))
return false;
return isMatch(s.substring(1),p.substring(1));
//Second character of p is '*'
}else{
int i=-1;
// first character of p equals first character of s keep matching
while(i<s.length() && (i<0 || p.charAt(0)=='.' || p.charAt(0)==s.charAt(i))){
if(isMatch(s.substring(i+1),p.substring(2)))
return true;
i++;
}
return false;
}
}
}
2. http://harrifeng.github.io/algo/leetcode/regular-expression-matching.html
public class Solution {
public boolean isMatch(String s, String p) {
if (p.length() == 0) {
return s.length() == 0;
}
// length == 1 is the case that is easy to forget.
// as p is subtracted 2 each time, so if original
// p is odd, then finally it will face the length 1
if (p.length() == 1) {
return (s.length() == 1)
&& (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.');
}
// next char is not '*': must match current character
if (p.charAt(1) != '*') {
if (s.length() < 1) {
return false;
} else {
return (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.')
&& isMatch(s.substring(1), p.substring(1));
}
}
// next char is *
while (s.length() > 0
&& (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')) {
if (isMatch(s, p.substring(2))) {
return true;
}
s = s.substring(1);
}
return isMatch(s, p.substring(2));
}
}
3. http://blog.csdn.net/fightforyourdream/article/details/17717873
类似于解释CodeGanker第一种方法的
public static boolean isMatch(String s, String p) {
return isM(s, p, 0, 0);
}
public static boolean isM(String s, String p, int i, int j){
if(j >= p.length()){ // pattern已经用光
return i >= s.length(); // 如果s已经走完则匹配,否则不匹配
}
if(j == p.length()-1){ // 如果pattern的j已经走到最后一个字符,如果想匹配,则s的i也必须在最后一个,且相等
return (i == s.length()-1) && (s.charAt(i)==p.charAt(j) || p.charAt(j)=='.');
}
// 如果pattern的下一个字符(j+1)不是*
if(j+1<p.length() && p.charAt(j+1) != '*'){
if(i == s.length()){ // 如果s已经走完,则说明不匹配
return false;
}
if(s.charAt(i)==p.charAt(j) || p.charAt(j)=='.'){ // 如果当前字符匹配
return isM(s, p, i+1, j+1); // 继续下一个字符判断
}else{ // 如果当前字符不匹配,直接返回false
return false;
}
}
// 如果下一个字符(j+1)是* 且 当前字符匹配,则进行搜索:
while(i<s.length() && j<p.length() && (s.charAt(i)==p.charAt(j) || p.charAt(j)=='.')){
// 因为*可以取0,1,2,...所以i=i,i+1,i+2,...对所有可能进行测试
// 最后能否匹配取决于剩下的匹配是否成功
if(isM(s, p, i, j+2)){ // 只要找到一个匹配成功即可
return true;
}
i++;
}
// 如果下一个字符(j+1)是* 且 当前字符不匹配,则pattern跳过两个,继续比较
// 还有一种情况到这里是上面的最后一次尝试(i==s.length())
return isM(s, p, i, j+2);
}