<leecode 第十题>
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。
‘.’ 匹配任意单个字符
‘*’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和*。
例如
1. aa 和 a*是匹配的 因为*可以匹配前面的字符0个或多个字符
2. ab和 .*是匹配的, 因为*可以的匹配 . 多个, 而. 可以匹配任意字符
我们仔细一想, 如果我们没有正则表达式字符, 只有普通的字符我想我们能很便捷的写出来,判断两个相不相等的代码
// 判断两个字符串是否相等
public static boolean dfs(String src, String dest) {
// 边界
if(src.length() == 0 && dest.length() == 0){
return true;
}
// 递归就是为了管好当下, 后面的交给递归
if(src.charAt(src.length() - 1) == dest.charAt(dest.length() - 1)){
return dfs(src.substring(0, src.length() - 1), dest.substring(0, dest.length() - 1));
}else{
return false;
}
}
好,目前我们已经实现了最基本的, 现在我们就要一层一层递进, 如果我们字符串中有 . 其实也是非常容易实现的, **.**可以代替任何字符
public static boolean dfs2(String src, String dest) {
if(src.length() == 0 && dest.length() == 0){
return true;
}
// 如果模式串正在匹配的数字是 . 那么我们也显示成功
if(src.charAt(src.length() - 1) == dest.charAt(dest.length() - 1) || dest.charAt(dest.length() - 1) == '.'){
return dfs(src.substring(0, src.length() - 1), dest.substring(0, dest.length() - 1));
}else{
return false;
}
}
下面, 我们就需要实现 *了, 因为*代替的字符不确定性,可以不匹配前面的字符, 也可以匹配多个, 难不成我们要一个一个试试?。。。,因为递归的特性就是管好当前, 其他的交给递归, 所以我们每一步面临的选择,就是要么选一次, 要么一次都不选, 因为在选了一次之后, 递归会帮我们选N次, 这样思考就好做了
// aab c*a*b
// *不会单独出现 他一定跟着某个字母出现
public static boolean dfs1(String src, String dest) {
// 记忆化搜索
if (map.containsKey(src + "&" + dest)) {
return map.get(src + "&" + dest);
}
// 如果匹配串没有了 那么根据原串可以得出结果
if (dest.length() == 0) {
map.put(src + "&" + dest, src.length() == 0);
return src.length() == 0;
}
// 判断第一个字符是否符合
boolean flag = false;
if (src.length() >= 1) {
flag = src.charAt(0) == dest.charAt(0) ? true : (dest.charAt(0) == '.' ? true : false);
}
// 如果第二个字符是*
if (dest.length() >= 2 && dest.charAt(1) == '*') {
// 1. *不匹配任何一个字符
// 2. * 匹配前面一个字符 匹配的话要检测前面是否能让你匹配
boolean aaa = dfs1(src, dest.substring(2)) || (flag && dfs1(src.substring(1), dest));
map.put(src + "&" + dest, aaa);
return aaa;
} else {
// 如果第二个不是* 那么大胆的走下去 吧第一个字符去掉
boolean aaa = flag && dfs1(dest.substring(1), dest.substring(1));
map.put(src + "&" + dest, aaa);
return aaa;
}
}