题解 | #正则表达式匹配#

正则表达式匹配

https://www.nowcoder.com/practice/28970c15befb4ff3a264189087b99ad4

package main

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param str string字符串
 * @param pattern string字符串
 * @return bool布尔型
 */
func match(str string, pattern string) bool {
	// write code here
	// 这个判断条件表示: 
	// if len(pattern) == 0 && len(str) == 0  return true;即如果字符串和模式串完全匹配,返回 true;举例:abc abc
	// if len(pattern) == 0 && len(str) != 0  return false; 即如果模式串已经用完,此时字符串还需要去匹配模式串,返回 false;举例:abc ab
	if len(pattern) == 0 {
		return len(str) == 0
	}

	// 这里判断主要为了要使用 pattern[1],所以为了防止越界我们作提前判断
	if len(pattern) == 1 {
		return len(str) == 1 && (str[0] == pattern[0] || pattern[0] == '.')
	}

	if pattern[1] == '*' {
		// 一. 如果第二个字符为 '*' 并且第一个字符匹配上,那么有三种状态可以转移
		//  1.* 表示前一个字符出现 0 次 2. * 表示前一个字符继续出现 3. * 表示前一个字符仅出现一次
		if len(str) > 0 && (pattern[0] == str[0] || pattern[0] == '.') {
			return match(str, pattern[2:]) || match(str[1:], pattern) || match(str[1:], pattern[2:])
		}

		// 二. 如果第一个字符没有匹配上,那么跳过模式串的前 2 个字符;举例:aaa b*aaa
		return match(str, pattern[2:])
	}

	// 正常匹配情形 但是为了防止越界,需要判断 str 的长度是否大于 0,如果不做判断,访问 str[0] 会 panic
	if len(str) > 0 && (pattern[0] == str[0] || pattern[0] == '.') {
		return match(str[1:], pattern[1:])
	}

	return false
}

最麻烦的情况就是匹配穿第二个字符是 '*',因为它可以表示它前面的字符出现 0 次~多次;

比如 a* 它可以表示 null 、a、aa、aaa ... ,因此我们需要确定这种情况下的状态转移;

在第二个字符为 '*' 时,也可以进一步分成两种情况:第一种是字符串第一个字符和模式串第一个字符匹配时,第二种情况是不匹配时;

当两个字符串首字符匹配时,有三种选择,第一种是让 * 表示前面的字符出现 0 次,直接跳过 a* ,使用模式串后面部分匹配 str;

第二种是让 * 表示前面的字符只出现 1 次,此时 a* 就表示 a,那么匹配上首字符,str 往后移动一个位置,pattern 往后移动两个位置(因为它使用 a* 代表一个 a);第三种情况就是让 * 表示前面的字符出现多次,让首字符继续匹配 str 后一个位置的字符,此时 str 移动,pattern 不需要移动。

而当两个字符串首字符不匹配时,移动模式串,使用模式串后面部分继续匹配字符串;比如 aaa b*aaa。

上面的代码中,len(str) > 0 && (pattern[0] == str[0] || pattern[0] == '.') 重用了很多次,所以这部分可以优化一下:

package main


/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param str string字符串
 * @param pattern string字符串
 * @return bool布尔型
 */
func match( str string ,  pattern string ) bool {
    // write code here
	if len(pattern) == 0 {
		return len(str) == 0
	}
	
	firstMatch := len(str) > 0 && (str[0] == pattern[0] || pattern[0] == '.')
	
	// 这里判断主要是后面要使用到 pattern[1],这里提前作越界判断
	if len(pattern) == 1 {
		return len(str) == 1 && firstMatch
	}

	if pattern[1] == '*' {
		// 如果第二个字符为 '*' 并且第一个字符匹配上,那么有三种状态可以转移
		// 1. * 表示前一个字符出现 0 次 2. * 表示前一个字符继续出现 3. * 表示前一个字符仅出现一次
		if firstMatch {
			return match(str, pattern[2:]) || match(str[1:], pattern) || match(str[1:], pattern[2:])
		}
		// 如果第一个字符没有匹配上,那么跳过模式串的前 2 个字符
		return match(str, pattern[2:])
	}
	
	// 正常匹配情形 但是为了防止越界,需要判断 str 的长度是否 > 0
	if firstMatch {
		return match(str[1:], pattern[1:])
	}

	return false
}

全部评论

相关推荐

评论
1
收藏
分享

创作者周榜

更多
正在热议
更多
# 长得好看会提高面试通过率吗? #
3498次浏览 43人参与
# HR最不可信的一句话是__ #
1044次浏览 32人参与
# MiniMax求职进展汇总 #
25032次浏览 321人参与
# 春招至今,你的战绩如何? #
15286次浏览 141人参与
# AI面会问哪些问题? #
916次浏览 22人参与
# 你的实习产出是真实的还是包装的? #
2907次浏览 52人参与
# 巨人网络春招 #
11509次浏览 224人参与
# 沪漂/北漂你觉得哪个更苦? #
1401次浏览 40人参与
# 你做过最难的笔试是哪家公司 #
1181次浏览 21人参与
# AI时代,哪个岗位还有“活路” #
2751次浏览 50人参与
# XX请雇我工作 #
51153次浏览 171人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7987次浏览 43人参与
# 简历第一个项目做什么 #
32109次浏览 359人参与
# 简历中的项目经历要怎么写? #
310971次浏览 4261人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152861次浏览 889人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187569次浏览 1123人参与
# AI时代,哪些岗位最容易被淘汰 #
64610次浏览 870人参与
# 如果重来一次你还会读研吗 #
229995次浏览 2011人参与
# 投格力的你,拿到offer了吗? #
178289次浏览 891人参与
# 你怎么看待AI面试 #
180721次浏览 1301人参与
# 正在春招的你,也参与了去年秋招吗? #
364274次浏览 2641人参与
# 腾讯音乐求职进展汇总 #
160837次浏览 1114人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务