题目
请实现一个函数用来匹配包括’.‘和’*‘的正则表达式。模式中的字符’.'表示任意一个字符,而 * 表示它前面的字符可以出现任意次(包含0次)。
在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是"aa.a"和"ab*a"均不匹配
解题思路
第一步:使用2个指针i,j对应目标数组和匹配数组,2个字符数组分别往后遍历。
- 如果2个指针同时到达length,则说明匹配成功,返回true
- 如果只有匹配的数组的j到达,则说明匹配数组并不能匹配目标数组,返回false
- 如果目标数组的i到达length,匹配数组仍未到达,若要匹配成功,则必须能匹配空数组,则说明剩下的字符必为偶数个,而且都是某个字符和*的组合,如果不是,返回false,是则为true
第二步:对字符进行匹配
- 如果pattern[j+1] == ‘*’,如果pattern[j]与str[i]不相等的话,则pattern[i]、pattern[j+1]只能当做0个字符处理;如果相等,则说明pattern[i]、pattern[j+1]能匹配str[i]或者不匹配i。
- 如果pattern[j+1] != ‘*’,直接进行判断,如果相等,则i、j往后移一位;如果不相等,直接返回false;
代码如下
public class Solution {
public boolean match(char[] str, char[] pattern) {
return helper(str, pattern, 0, 0);
}
public boolean helper(char[] str, char[] pattern, int i, int j) {
//递归结束判断
if (i == str.length && j == pattern.length) {
return true;
}
//匹配数组提前结束,则不匹配
if (j == pattern.length) return false;
if (i == str.length && j < pattern.length) {
//目标数组匹配完,匹配数组只能为某个字符与*的组合,并且剩余长度为偶数
if ((pattern.length - j) % 2 != 0 )return false;
for (; j < pattern.length; j += 2) {
if (pattern[j + 1] != '*') return false;
}
return true;
}
//处理pattern[j+1]为*的情况
if (j + 1 < pattern.length && pattern[j + 1] == '*') {
if (judge(str[i], pattern[j])) {
return helper(str, pattern, i + 1, j) || helper(str, pattern, i, j + 2);
} else {
return helper(str, pattern, i, j + 2);
}
} else if (judge(str[i], pattern[j])) {
return helper(str, pattern, i + 1, j + 1);
} else {
return false;
}
}
public boolean judge(char a, char b) {
if (b == '.') return true;
return a == b;
}
}