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

正则表达式匹配

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
}

全部评论

相关推荐

爪哇沉淀ing:哎 感觉很丰富 其实没啥含金量 我本科也是理工的 实话实说这个学校真的没啥竞争力 建议还是提升学历
今天你投了哪些公司?
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
正在热议
更多
# 长得好看会提高面试通过率吗? #
4724次浏览 49人参与
# 离家近房租贵VS离家远但房租低,怎么选 #
16931次浏览 137人参与
# 米连集团26产品管培生项目 #
7480次浏览 230人参与
# 沪漂/北漂你觉得哪个更苦? #
1725次浏览 42人参与
# 你的实习产出是真实的还是包装的? #
3283次浏览 55人参与
# 春招至今,你的战绩如何? #
16326次浏览 148人参与
# 巨人网络春招 #
11573次浏览 230人参与
# HR最不可信的一句话是__ #
1143次浏览 33人参与
# AI面会问哪些问题? #
1005次浏览 26人参与
# 你做过最难的笔试是哪家公司 #
1347次浏览 23人参与
# AI时代,哪个岗位还有“活路” #
3025次浏览 53人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152968次浏览 889人参与
# 简历第一个项目做什么 #
32220次浏览 364人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
8037次浏览 43人参与
# XX请雇我工作 #
51167次浏览 171人参与
# 简历中的项目经历要怎么写? #
311203次浏览 4274人参与
# 投格力的你,拿到offer了吗? #
178411次浏览 891人参与
# 你最满意的offer薪资是哪家公司? #
77025次浏览 375人参与
# AI时代,哪些岗位最容易被淘汰 #
64919次浏览 895人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187673次浏览 1123人参与
# 你怎么看待AI面试 #
180946次浏览 1325人参与
# 正在春招的你,也参与了去年秋招吗? #
364447次浏览 2642人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务