题目描述
请实现一个函数用来匹配包括’.‘和星号的正则表达式。模式中的字符’.'表示任意一个字符,而星号表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配。
代码思路
当模式中的第二个字符是星号时:
如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配(相当于星号前面的)。如果字符串第一个星号字符跟模式第一个字符匹配,可以有3种匹配方式:
1.模式后移2字符,相当于x星号被忽略;
2.字符串后移1字符,模式后移2字符,相当于x星号匹配一位;
3.字符串后移1字符,模式不变,即继续匹配字符下一位,相当于x星号匹配多位;
当模式中的第二个字符不是星号时:
如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的部分。
如果字符串第一个字符和模式中的第一个字符相不匹配,直接返回False。
错误代码反思
由于写代码之前没有认真思考 str和pattern 的关系,写出了如下代码
public class Solution {
public boolean match(char[] str, char[] pattern)
{
if (str == null || pattern == null)
return false;
return matchcore(str, pattern,0,0);
}
private boolean matchcore(char[] str, char[] pattern, int s, int p){
if(str.length == s && pattern.length == p)
return true;
if (s < str.length && p == pattern.length)
return false;
//错误1:
if(s == str.length && p < pattern.length)
return false;
if(pattern[p+1] == '*'){//错误二
if(pattern[p]=='.' || pattern[p] == str[s])//错误三
return matchcore(str, pattern, s+1,p)||
matchcore(str, pattern, s+1,p+2)||
matchcore(str, pattern, s,p+2);
else
return matchcore(str, pattern, s,p+2);
}
if(pattern[p]=='.' || pattern[p] == str[s])//错误四
return matchcore(str, pattern, s+1,p+1);
return false;
}
}
错误一:没有考虑特殊情况。当str的指针指向最后一个元素时,如果pattern最后两个元素为.* 那么仍然是匹配成功的情况。
错误二:当变量作为数组下表出现时,没有注意边界的判定。
错误三:因为接下来涉及到s+1作为方法参数,必须确保s+1<=str.length,错误四同理。
修改后的代码
public class Solution {
public boolean match(char[] str, char[] pattern)
{
if (str == null || pattern == null)
return false;
return matchcore(str, pattern,0,0);
}
private boolean matchcore(char[] str, char[] pattern, int s, int p){
if(str.length == s && pattern.length == p)
return true;
if (s < str.length && p == pattern.length)
return false;
if(p + 1 < pattern.length && pattern[p+1] == '*'){
if ((s < str.length && pattern[p] == '.')|| (s < str.length && pattern[p] == str[s]))
return matchcore(str, pattern, s+1,p)||
matchcore(str, pattern, s+1,p+2)||
matchcore(str, pattern, s,p+2);
else
return matchcore(str, pattern, s,p+2);
}
if(s < str.length && (pattern[p]=='.' || pattern[p] == str[s]))
return matchcore(str, pattern, s+1,p+1);
return false;
}
}