leetcode 10. 正则表达式匹配

https://leetcode-cn.com/problems/regular-expression-matching/

解题思路

dp[0][0] = true; //主串前0个字符(空串) 和 模式串 前0个字符(空串) 能够匹配

for(int j = 2; j <= n; j++) {
     if(p[j - 1] == '*' && j >= 2)
         dp[0][j] = dp[0][j - 2];  //把主串当做空串的时候和模式串中带有*的比较,主要是由于*可以吃掉一部分主串 所以也有可能匹配上 比如空串 和 "a*b*c*"是匹配的
}


(一)当前字符匹配,或者模式字符是'.' : dp[i][j] = dp[i-1][j-1];
(二)当前模式字符是'*':


当前字符是p[j-1]='*',需要看其前一个字符p[j-2]与主字符s[i-1]是否匹配,前一个字符p[j-2] 是点或者 与主字符s[i-1]相等则匹配,否则不匹配。

(1)前一个字符p[j-2]与主字符s[i-1]匹配 : (去掉谁,谁就减, 减多少就看去掉了几个字符)

(1.1)则可以参考去掉模式串的值是否匹配,假如当前两个字符都是a, 也就是 去掉'a*'看是否匹配, 对应:
dp[i][j] = dp[i][j - 2];
(1.2)或者参考去掉当前主字符后是否匹配,即仅仅去掉当前主字符a, 对应 dp[i][j] = dp[i - 1][j];

(2)前一个字符p[j-2]与主字符s[i-1]不匹配 : 必须去掉模式串'a*'来作为dp[i][j], 即 dp[i][j] = dp[i][j - 2]。

代码:

bool isMatch(string s, string p) {
	int m = s.length(), n = p.length();
	bool dp[m + 1][n + 1];
	memset(dp, false, sizeof(dp));
	dp[0][0] = true; //主串前0个字符(空串) 和 模式串 前0个字符(空串) 能够匹配
	for(int j = 2; j <= n; j++) {
		if(p[j - 1] == '*' && j >= 2) dp[0][j] = dp[0][j - 2];
	}
	for(int i = 1; i <= m; i++) {
		for (int j = 1; j <= n; j++) {
			if(s[i-1] == p[j-1] || p[j-1] == '.'){
				dp[i][j] = dp[i-1][j-1]; //(一)当前字符匹配,或者模式字符是'.'
			} else if(p[j - 1] == '*'){//(二)当前模式字符是'*'
			    //当前字符是p[j-1]='*',需要看其前一个字符p[j-2]与主字符s[i-1]是否匹配
                bool flag = j >= 2 && (s[i - 1] == p[j - 2] || p[j - 2] == '.'); //前一个字符p[j-2] 是点或者 与主字符s[i-1]相等 则匹配
				//(1)前一个字符p[j-2]与主字符s[i-1]匹配 : (去掉谁,谁就减, 减多少就看去掉了几个字符)
				//   (1.1)则可以参考去掉模式串的值是否匹配,假如当前两个字符都是a, 也就是 去掉'a*'看是否匹配 对应 dp[i][j] = flag && dp[i][j - 2];
				//   (1.2)或者参考去掉当前主字符后是否匹配,即仅仅去掉当前主字符a, 对应 dp[i][j] = flag && dp[i - 1][j];
				//(2)前一个字符p[j-2]与主字符s[i-1]不匹配 : 必须去掉模式串'a*'来作为dp[i][j], 即 dp[i][j] = dp[i][j - 2]
				dp[i][j] =  flag && (dp[i][j - 2] || dp[i - 1][j]) || dp[i][j - 2]; 
			}
		}
	}
	return dp[m][n];
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
正则表达式匹配是一个经典的算法问题,主要是判断一个字符串是否能够完全匹配给定的正则表式。 在LeetCode上,也有一道关于正则表达式匹配的题目,题目编号是10。这道题目要求实现一个支持 '.' 和 '*' 的正则表达式匹配,其中 '.' 可以匹配任意单个字符,'*' 可以匹配零个或多个前面的元素。 解决这道题可以使用动态规划的思想,具体的思路如下: 1. 创建一个二维数组dp,dp[i][j]表示s的前i个字符与p的前j个字符是否匹配。 2. 初始化dp为true,表示空字符串与空正则表达式是匹配的。 3. 初始化dp[i]为false,表示非空字符串与空正则表达式是不匹配的。 4. 初始化dp[j],如果p[j-1]是"*",则dp[j]的值取决于dp[j-2]的值,表示将p[j-2]与p[j-1]去掉后的正则表达式是否匹配空字符串。 5. 对于其它的dp[i][j],分成两种情况: - 如果p[j-1]是"."或者与s[i-1]相等,则dp[i][j]的值取决于dp[i-1][j-1]的值,表示将s[i-1]和p[j-1]去掉后的字符串是否匹配。 - 如果p[j-1]是"*",则dp[i][j]的值取决于以下两种情况: - dp[i][j-2]的值,表示将p[j-2]和p[j-1]去掉后的正则表达式是否匹配s的前i个字符。 - dp[i-1][j]的值,表示将s[i-1]与p[j-2]匹配后的字符串是否匹配p的前j个字符。 6. 最后返回dp[s.length()][p.length()]的值,表示整个字符串s与正则表达式p是否完全匹配。 以上是一种使用动态规划解决正则表达式匹配问题的思路,具体的实现可以参考LeetCode官方提供的递归思路的解法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [LeetCode算法 —— 正则表达式匹配(详解官方动态规划思想)](https://blog.csdn.net/weixin_42100963/article/details/106953141)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值