题目
题目描述
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配
解
关键就是分析好情况,如果第二个字符是*,可能有多种情况:
- 当前字符参与一次匹配,pattern串向前两个位置;
- 当前字符不参与匹配(即取*的使用0次的情况),pattern串向前两个位置;
- 当前字符参与多次匹配,pattern串不向前移动位置
链接:https://www.nowcoder.com/questionTerminal/45327ae22b7b413ea21df13ee7d6429c
来源:牛客网
当模式中的第二个字符不是“*”时:
1、如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的。
2、如果 字符串第一个字符和模式中的第一个字符相不匹配,直接返回false。
而当模式中的第二个字符是“”时:
如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。如果字符串第一个字符跟模式第一个字符匹配,可以有3种匹配方式:
1、模式后移2字符,相当于x被忽略;
2、字符串后移1字符,模式后移2字符;
3、字符串后移1字符,模式不变,即继续匹配字符下一位,因为*可以匹配多位;
下面是鄙人连抄带写的代码,难登大雅之堂。
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 ss, char[] pattern, int ps){
if (ss == str.length && ps == pattern.length) {
return true;
}
if (ss != str.length && ps == pattern.length) {
return false;
}
// 如果第二个字符为*
if(ps + 1 < pattern.length && pattern[ps + 1] == '*'){
// 如果当前字符相同
if(ss != str.length && str[ss] == pattern[ps]
|| ss != str.length && pattern[ps] == '.'){
return helper(str, ss + 1, pattern, ps)
|| helper(str, ss + 1, pattern, ps + 2)
|| helper(str, ss, pattern, ps + 2);
}else{
// 如果当前字符不同
return helper(str, ss, pattern, ps + 2);
}
}
// 如果第二个字符不为*
if(ss != str.length && pattern[ps] == '.'
|| ss != str.length && str[ss] == pattern[ps]){
return helper(str, ss + 1, pattern, ps + 1);
}
return false;
}