正则表达式匹配实现

<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;
		}

	}

猜你喜欢

转载自blog.csdn.net/weixin_44112559/article/details/107039486