44.通配符匹配

 

分析:

这道题通配符外卡匹配问题还是小有难度的,有特殊字符 ‘*’ 和 ‘?’,其中 ‘?’ 能代替任何字符,‘*’ 能代替任何字符串,注意跟另一道 Regular Expression Matching 正则匹配的题目区分开来。两道题的星号的作用是不同的,注意对比区分一下。这道题最大的难点,就是对于星号的处理,可以匹配任意字符串,简直像开了挂一样,就是说在星号对应位置之前,不管你s中有任何字符串,我大星号都能匹配你,主角光环啊。但即便叼如斯的星号,也有其处理不了的问题,那就是一旦p中有s中不存在的字符,那么一定无法匹配,因为星号只能增加字符,不能消除字符,再有就是星号一旦确定了要匹配的字符串,对于星号位置后面的匹配情况也就鞭长莫及了。所以p串中星号的位置很重要,用 jStar 来表示,还有星号匹配到s串中的位置,使用 iStart 来表示,这里 iStar 和 jStar 均初始化为 -1,表示默认情况下是没有星号的。然后再用两个变量i和j分别指向当前s串和p串中遍历到的位置。

开始进行匹配,若i小于s串的长度,进行 while 循环。若当前两个字符相等,或着p中的字符是问号,则i和j分别加1。若 p[j] 是星号,要记录星号的位置,jStar 赋为j,此时j再自增1,iStar 赋为i。若当前 p[j] 不是星号,并且不能跟 p[i] 匹配上,此时就要靠星号了,若之前星号没出现过,那么就直接跪,比如 s = "aa" 和 p = "c*",此时 s[0] 和 p[0] 无法匹配,虽然 p[1] 是星号,但还是跪。如果星号之前出现过,可以强行续一波命,比如 s = "aa" 和 p = "*c",当发现 s[1] 和 p[1] 无法匹配时,但是好在之前 p[0] 出现了星号,把 s[1] 交给 p[0] 的星号去匹配。至于如何知道之前有没有星号,这时就能看出 iStar 的作用了,因为其初始化为 -1,而遇到星号时,其就会被更新为i,只要检测 iStar 的值,就能知道是否可以使用星号续命。虽然成功续了命,匹配完了s中的所有字符,但是之后还要检查p串,此时没匹配完的p串里只能剩星号,不能有其他的字符,将连续的星号过滤掉,如果j不等于p的长度,则返回 false,

代码如下:

class Solution {
public:
    bool isMatch(string s, string p) {
        int i = 0, j = 0, iStar = -1, jStar = -1, m = s.size(), n = p.size();
        while (i < m) {
            if (j < n && (s[i] == p[j] || p[j] == '?')) {
                ++i; ++j;
            } else if (j < n && p[j] == '*') {
                iStar = i;
                jStar = j++;
            } else if (iStar >= 0) {
                i = ++iStar;
                j = jStar + 1;
            } else return false;
        }
        while (j < n && p[j] == '*') ++j;
        return j == n;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值