题目描述
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。
这道题主要是把思路捋清楚了就Ok.用指针来实现,能匹配上,指针就后移;
分成两大类
1. 模式中的第二个字符不是 *
这种情况比较简单,只需判断字符串中的第一个字符是否和模式中的第一个字符匹配即可。匹配就两者指针均后移一位,不匹配直接拉到。匹配的情况有
字符对应字符 或者 字符对应‘.’
2. 模式中的第二个字符是 *
a. 字符串中的第一个字符和模式中的第一个字符不匹配,则字符串指针不动,模式指针后移两位,代表*匹配了0次;
b. 字符串中第一个字符和模式中的第一个字符匹配,则有三种搞法:
# 字符串指针不动,模式指针后移两位,代表*匹配了0次;
# 字符串指针后移一位,模式指针后移两位,代表*匹配了1次;
# 字符串指针后移一位,模式指针不动,代表*要匹配两次以上;
"" , ".*" true
"","." false
从上面两个测试用例,可知该题要格外注意边界;
还有一个弱智问题卡了我很久,最后只能打印出来一步步对,才发现 ++i是会改变i的值的啊朋友!!!那么我这三种情况或的时候保准有问题,传参的时候老实用+1不好吗?哭泣
运行时间:22ms
占用内存:9176k
public class Solution {
public boolean match(char[] str, char[] pattern)
{
if(str == null || pattern == null)
return false;
return helper(str, 0, pattern, 0);
}
private boolean helper(char[] str, int stri, char[] pattern, int pi){
//两个数组都遍历结束,匹配成功
if(stri == str.length && pi == pattern.length)
return true;
//"根据"aaa""aa.a"只要两个数组不是同时到达尾部,都没有匹配成功" 这句话错误,反例"",".*"
if(pi == pattern.length)
return false;
//首先分成两大类,就是根据第二位是不是*来分
if(pi + 1 < pattern.length && pattern[pi + 1] == '*'){
//模式中*前面一位的字符和字符串当前位是否匹配
//"",".*" || "","."
if((stri < str.length && pattern[pi] == str[stri]) || (pattern[pi] == '.' && stri < str.length)){
//三种情况:
return helper(str, stri, pattern, pi + 2)
|| helper(str, stri+1, pattern, pi + 2)
|| helper(str, stri+1, pattern, pi);
}
else{
return helper(str, stri, pattern, pi + 2);
}
}
else{
if((stri < str.length && pattern[pi] == str[stri]) || (pattern[pi] == '.' && stri < str.length))
return helper(str, stri+1, pattern, pi+1);
else
return false;
}
}
}