Regular Expression Matching

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.

总结下问题:简易的正则表达式匹配,如果s为空,p也为空,那么匹配结果为true;如果s为"a",p为"*",那么匹配结果为false;s只能是[a-z]的元素组成;p只能是[a-z.*]的元素组成.

思路:有两种思路,递归和动态规划。递归很好理解,网上的答案也是正确的。但是动态规划的求解代码,网上却有很多的错误答案(官方还能运行通过!),这个会在后面验证说明。

一,递归:考察p模式,@1 如果p为空,那么结果取决于s是否为空,s为空返回true,不为空返回false.                                                                                   @2 如果p只有一个字符,那么匹配结果取决于(s.size() ==1) && (s[0] == p[0] || p[0] == '.' )                                                                 @3 除了上述情况,那么p至少有2个字符;对p的p[1]判断,如果p[1]是非'*'字符,那么结果取决于 s.empty() || (s[0] == p[0] || p[0] == '.' )  &&  isMatch(s.substr(1),p.substr(1))。 如果p[1]是'*'号,那么判断*号重复前面字符0次,1次,2次...是否匹配,一旦匹配返回true,否则每次判断都缩小s的范围,确保能循环终止。

二,动态规划:参考官网上solution的jianchao-li的帖子,

  1. P[i][j] = P[i - 1][j - 1], if p[j - 1] != '*' && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
  2. P[i][j] = P[i][j - 2], if p[j - 1] == '*' and the pattern repeats for 0 times;
  3. P[i][j] = P[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.'), if p[j - 1] == '*' and the pattern repeats for at least 1 times.

这个思路够清晰了,但是贴出来的代码却是错误的,如果s="",p="*",程序立马崩溃!但官网上还是能运行通过。

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.length(), n = p.length(); 
        vector<vector<bool> > dp(m + 1, vector<bool> (n + 1, false));
        dp[0][0] = true;
        for (int i = 0; i <= m; i++)
            for (int j = 1; j <= n; j++)
                if (p[j - 1] == '*')
                    dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]);
                else dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
        return dp[m][n];
    }
};

附加递归代码:

附加动态规划代码:

附加测试用例:

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值