[leetcode] 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
class Solution {
public:
	bool isMatch(const char *s, const char *p) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		int i , j, k;
		int lengths,lengthp;
		i=j=k=lengths=lengthp=0;
		lengths=strlen(s);
		lengthp=strlen(p);
		if(lengths==0 && lengthp==0)
			return true;
		if(lengthp==1){
			if(*p=='*')
				return true;
			else if(*p=='?'){
				if(lengths==1)
					return true;
				else
					return false;
			}
			else{
				if(lengths==1)
					return *s==*p;
				else
					return false;
			}

		}else{
			if(*p=='?')
				return isMatch(++s,++p);
			else if(*p=='*'){
				for(j=0 ; j<lengthp ; j++){
					k|=isMatch(s+j,++p);
				}
				return k;
			}
			else{
				if(*s==*p)
					return isMatch(++s,++p);
				else
					return false;
			}
		}
	}
};

上面这个递归是我自己写的,思路很简单了,主要分为以下几个关键的部分:

1. 当遇到?时,那么可以匹配任意的源字符串中的一个字符,我们只需递归的匹配下一个通配符串和下一个源字符串。
2. 当遇到*时,那么可以匹配任意的源字符串,那么我们就从0个字符开始递归匹配。
3. 最简单的是普通字符,那么直接匹配,再匹配下面的字符串。

发现一个不错的链接:

http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html

这里面介绍了一些不错的通配符匹配的算法,看了看他写的比我好多了!!!自己的代码确实跟屎一样。然后我就稍微把他的代码更改了一下,他似乎是一个极其热爱和平的人,哈哈哈哈:

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		while(*p){
			switch(*p){
				case '?':
//					if(*s=='')
				if(*s)return isMatch(++s,++p);
				else return false;
				break;
				case '*':
					for(p++;*p!='*';p++);
					if(!*p)return true;
					while(*s)if(isMatch(s++,p))return true;
					return false;
				default:
					if(*s!=*p)return false;
					break;
			}
			p++,s++;
		}
		for(;*p=='*';p++);
		return ((!*p)&&(!*s));
	}
};

这代码用到了递归,是不能通过大数据的。当然如果你认为这种代码就已经够简洁的话那你就图样图森破了。代码可以简洁到下面这个样子:

class Solution {
public:
	bool isMatch(const char *s, const char *p) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		switch(*p){
			case '\0':
				return !*s;
			case '*':
				return isMatch(s,p+1) || *s && isMatch(s+1,p);
			case '?':
				return *s && isMatch(s+1,p+1);
			default:
				return (*s==*p) && isMatch(s+1,p+1);
		}
	}
};

上面的都是递归的解法,递归的解法效率永远是硬伤!下面介绍非递归的解法:

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		int i,star;
	new_segment:
		star=0;
		if(*p=='*'){
			star=1;
			for(p++;*p=='*';p++);
		}
	test_match:
		for(i=0 ; p[i] && (p[i]!='*');i++){
			if(s[i]!=p[i]){
				if(!s[i])return false;
				if((p[i]=='?') && s[i]) continue;
				if(!star)return false;
				s++;
				goto test_match;
			}		
		}
		if(p[i]=='*'){
			s+=i;
			p+=i;
			goto new_segment;
		}
		if(!s[i])return true;
		if(i && p[i-1]=='*') return true;
		if(!star) return false;
		s++;
		goto test_match;
	}
};

这里面用到了goto语句,我会考虑将goto去除的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值