【剑指Offer19-正则表达式匹配】

题目:
在这里插入图片描述
这题难是真的难,不好思考到动态规划上面。虽然字符串匹配问题,动态规划基本上是通解,但是这题是真的难想。

大体上来说,分为两种情况。

p的当前字符是否为“*”?
如果是的话,则有两种选择:
让前一个字符重复一次或者删除掉前一个字符。(为什么不重复多次呢?因为是遍历,每一次只会考虑动态增长1或减少1的情况,多次增长交给下一次遍历去处理。这里我也是后来才想通)
那么重复的情况下,如果前一个字符是".",则也是可以令当前字符为True的。

如果不是:
则去匹配当前字符,同时,匹配的时候也检查p的当前字符是否为"."。这样就很明了。

除此之外,首行的初始化也要注意,因为p是可以出现"*"的。
所以即使s是空字符串,也会被p例如“a** ”这样的字符串匹配掉。

具体细节看代码:

#include<iostream>
#include<string>
#include<vector>

using namespace std;

class Solution {
public:
    bool isMatch(string s, string p) {
		int m = s.length() + 1;
		int n = p.length() + 1;
		vector<vector<bool>> dp(m,vector<bool>(n,false));
		dp[0][0] = true;//空字符串可以匹配 
		for(int j = 2;j<n;j++){
			dp[0][j] = dp[0][j - 2] && p[j - 1] == '*';
		}
		for(int i=1;i<m;i++){
			for(int j=1;j<n;j++){
				if(p[j - 1] == '*') {
                    if(dp[i][j - 2]) dp[i][j] = true;                              // 1.舍弃掉p的i-1个字符 
                    else if(dp[i - 1][j] && s[i - 1] == p[j - 2]) dp[i][j] = true; // 2.令p的字符重复一次 
                    else if(dp[i - 1][j] && p[j - 2] == '.') dp[i][j] = true;      // 3.令p的字符重复一次(与上面的情况相同) 
                } else {
                    if(dp[i - 1][j - 1] && s[i - 1] == p[j - 1]) dp[i][j] = true;  // 1.普通字符配对 
                    else if(dp[i - 1][j - 1] && p[j - 1] == '.') dp[i][j] = true;  // 2.普通字符配对,p可以变成s【i-1】,本质上与第一种是一样的 
                }
			}
		}
		return dp[m-1][n-1]; 
    }
};

int main(){
	string s = "aaa";
	string p = "ab*.*";
	Solution solution;
	cout<<solution.isMatch(s,p); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值