leetcode(44) - Wildcard Matching

思路

假设我们用两个指针分别指向s和p字符串中要匹配的位置,首先分析下通配符匹配过程中会有哪些情况是成功:

  1. s的字符和p的字符相等

  2. p中的字符是?,这时无论s的字符是什么都可以匹配一个

  3. p中遇到了一个*,这时无论s的字符是什么都没关系

  4. 之前的都不符合,但是p在之前的位置有一个*,我们可以从上一个*后面开始匹配

  5. s已经匹配完,但是p后面还有很多连续的`*

这里1和2的情况比较好处理,关键在于如何处理3和4的情况。当我们遇到一个*时,因为之后可能要退回至该位置重新匹配,我们要将它的下标记录下来,比如idxstar。但是,当我们连续遇到两次4的情况,如何保证我还是能继续匹配s,而不是每次都退回idxstar+1导致循环呢?所以我们还要记录一个idxmatch,用来记录用上一个*连续匹配到的s中的下标。最后,对于情况5,我们用一个循环跳过末尾的*跳过就行了。

代码

public class Solution {
    public boolean isMatch(String s, String p) {
        int idxs = 0, idxp = 0, idxstar = -1, idxmatch = 0;
        while(idxs < s.length()){
            // 当两个指针指向完全相同的字符时,或者p中遇到的是?时
            if(idxp < p.length() && (s.charAt(idxs) == p.charAt(idxp) || p.charAt(idxp) == '?')){
                idxp++;
                idxs++;
            // 如果字符不同也没有?,但在p中遇到是*时,我们记录下*的位置,但不改变s的指针
            } else if(idxp < p.length() && p.charAt(idxp)=='*'){
                idxstar = idxp;
                idxp++;
                //遇到*后,我们用idxmatch来记录*匹配到的s字符串的位置,和不用*匹配到的s字符串位置相区分
                idxmatch = idxs;
            // 如果字符不同也没有?,p指向的也不是*,但之前已经遇到*的话,我们可以从idxmatch继续匹配任意字符
            } else if(idxstar != -1){
                // 用上一个*来匹配,那我们p的指针也应该退回至上一个*的后面
                idxp = idxstar + 1;
                // 用*匹配到的位置递增
                idxmatch++;
                // s的指针退回至用*匹配到位置
                idxs = idxmatch;
            } else {
                return false;
            }
        }




bool isMatch(char* s, char* p) {
    char* p_pos=NULL,*s_pos=NULL;
    
    while(*s){                // 这里判断s[i]!='\0'不是字符串结束条件
    
        if(*p == *s || *p == '?'){  // 单个字符匹配的情况,?匹配单个字符
            p++;
            s++;
            continue;
        }
        
        if(*p=='*')  // 如果当前p为*,因为*可以匹配多个元素,因此需要寻找匹配位置。p_pos为*的下一个位置
            p++;
            p_pos = p;
            s_pos = s;
            continue;
        }
        
        if(s_pos != NULL){  
            s_pos++;
            s = s_pos;
            p = p_pos;
            continue;
        }
        
        return false;  
    }
    
    while(*p && *p == '*'){  //如果s处理完了,p还不为空,如果匹配的话,只允许接下来的字符是*
        p++;
    }
    
    return !*p;

}







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值