Wildcard Matching


Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

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

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true

isMatch("aab", "c*a*b") → false

动态规划请参考:动态规划解法

递归方法:(TLE)

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        if( 0 == *p) return 0 == *s;
        if(*p == '*'){
            while(*(p+1) == '*')p++;
            while((*s) != 0){
                if(isMatch(s,p+1))return true;
                s++;
            }
            return isMatch(s,p+1);
        }
        else{
            if(((*s) != 0) && ((*s) == (*p) || (*p) == '?')){
                return isMatch(s+1,p+1);
            }
            return false;
        }
    }
};



水平有限,调代码调的比较久,边界问题总是弄不清楚,要死的节奏。
这里当前面和后面均有*号的时候,本来想用kmp,可是KMP也不是很熟,而且这里还有?号。
总体思想是:分析 p 串,把其中每个单词均解析出来,然后用贪心的方法进行匹配,匹配后要保存匹配到 s 中的位置。
总体还是过了,232ms,前面的递归方法TLE。

贪心方法

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        //greedy
        bool pre,next;
        const char *start,*end,*mid;
        const char *ss,*se,*sm;
        start = p;
        end = p;
        ss = s;
        while(true){
            if(*start == '*')pre = true;//查看前面有没有*
			else pre = false;
            //查看新的没有*的word
            while(*start != '\0' && *start == '*')start++;
            end = start;
            
            while(*end != '\0' && *end != '*')end++;
            if(*end == '*')next = true;
			else next = false;
			end--;
            
            if(*ss == '\0' && pre && *start == '\0')return true;//p和s均完全匹配
            if(*ss != '\0' && pre && *start == '\0')return true;
            if(*ss != '\0' && (*start == '\0' && !pre))return false;//s没能完全匹配
            if(*ss == '\0' && *start != '\0')return false;//p的字母没能匹配完全
            
            //处理greedy匹配问题
            if(next == true){//后面有*可供匹配
                if(pre == true){//前面有供做匹配的
					sm = ss,mid = start;//判断s中剩余的还够匹配不够
                    while(mid != end && *sm != '\0'){
                        mid++,sm++;
                    }
                    if(*sm == '\0')return false;

					mid = start;
                    while(*mid != '*' && *ss != '\0'){
                        for(sm = ss,mid = start;*sm != '\0' && *mid != '*';sm++,mid++){
                            if(*mid == '?')continue;
                            if(*mid != *sm)break;
                        }
                        if(*mid == '*')ss = sm;
                        else ss++;
                    }//while
                    if(*mid != '*')return false;
					ss = sm;
					start = mid;
                }
                else{//前面没有供匹配的
                    for(sm = ss,mid = start;*sm != '\0' && mid != end+1;sm++,mid++){
                        if(*mid == '?')continue;
                        if(*mid != *sm)return false;
                    }
                    if(mid != end+1)return false;
                    ss = sm;//匹配成功
					start = end+1;
                }
            }
            else{//最后必须匹配的一串,因为后面没有*可供匹配最后的字母
				if(pre){
					se = ss;
					while(*se != '\0')
						se++;
					se--;
					for(sm = se,mid = end;mid != start && sm != ss;mid--,sm--){
						if(*mid == '?')continue;
						if(*mid != *sm)return false;
					}
					if((sm == ss && mid != start) || (*mid != *sm && *mid != '?'))return false;//如果s不够匹配或者p开头不能匹配
					return true;
				}
				else{
					for(sm = ss,mid = start;*sm != '\0' && *mid !='\0';sm++,mid++){
						if(*mid == '?')continue;
						if(*mid != *sm)return false;
					}
					if(*sm != '\0' || *mid != '\0')return false;
					return true;
				}
                
            }
        }
    }
};


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值