题目
请实现一个函数用来匹配包括’.‘和星号的正则表达式。模式中的字符’.'表示任意一个字符,而星号表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab星号ac星号a"匹配,但是与"aa.a"和"ab*a"均不匹配
分析
思路一:
代码:
public class Solution {
public boolean match(char[] str, char[] pattern)
{
return match(str, 0, pattern, 0);
}
public boolean match(char[] s, int i, char[] e, int j) {
//1. 如果j 到了exp.length 而i 还没到str.length ,返回false ,否则返回true
if (j == e.length) {
return i == s.length;
}
//2. (潜台词:j位置有字符)j上面还有字符,考察j+1的情况
if (j + 1 == e.length || e[j + 1] != '*') {//j+1位置没字符或者j+1位置不为*
//要求此时i位置有字符
return i != s.length && (s[i] == e[j] || e[j] == '.') && match(s, i + 1, e, j + 1);
}
//3. (潜台词:j和j+1位置有字符)上述两种情况都不满足,即j+1不越界,并且e[j+1]为'*'
while (i != s.length && (e[j] == s[i] || e[j] == '.')){
//str[i] = exp[j] 或exp[j]='.' 。比如a* 可以匹配空串也可以匹配一个a ,如果str[i] 之后还
//有连续的相同字符,那么a* 还可以匹配多个,不管是哪种情况,将匹配后右移的i 和j 交给子过程
//match
if (match(s, i, e, j + 2)) {//如果*个数选择0,则表示e[j]选择0个,j右移两格继续判断
return true;
}
i++;//如果选择0个的时候不匹配,选择*个数为1,str中的i向右移一格继续判断,j不动
//即继续判断*为2个,3个。。。的时候,以此类推
}
//如果上面的while是因为 s[i]!=e[j] 而停止的,j 之后的字符只能是a*b*c*.* 的形式,也就是
//一个字符后必须跟一个* 的形式,这个检验过程同样可以交给match 来做
return match(s, i, e, j + 2);//s[i]!=e[j],j+1位置的*应为0,然后看j+2位置开头的字符是否与i匹配
}
}