leetcode: wildcard matching

Implement wildcard pattern matching with support for '?' and '*'.  (未 0902)

http://www.xuebuyuan.com/1936978.html

'?' 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
算法提交结果:Time Limit Exceeded
算法的思想:1): *S = *P or *P =‘?’时,S++, P++;
2): *P = '*' 时,保存当前最靠后(最新)的*的后面的一个数值 记为:start_P = P+1, start_S = 当前的S
3): 将 *S 与 *P 的值做比较,转1);若 *S 与 *P 的值不相等,则 重置 S 和 P 为start_S + 1 和start_P;
转 1),如此循环以上3步;
#include<iostream>
using namespace std;

class Solution {
public:
	bool isMatch(const char *s, const char *p) {
		bool start = false;
		const char *start_s ;
		const char *start_p ;
		int pLen = 0;
		while (*s != '\0')
		{
			if (*p != '\0' &&( *s == *p || *p == '?'))
			{
				s++; p++;
			}
			if (start == true && *s != *p)
			{
				s = start_s + 1;
				while (*s != '\0' && *s != *start_p)
					s++;		
				p = start_p;
			}
			
			else if (*p == '*')
			{
				start = true;
				while (*(p + 1) == '*' && *(p + 1) != '\0')
					p++;
				if (*(p + 1) == '\0')
				{
					return true;
				}
				else
				{
					p++;
					start_s = s;
					start_p = p;
				}
			}
		}			
		if (*p == '\0' && *s == '\0')
			return true;
		else
			return false;
	}
};
void main()
{
	 char *s = "abcdeade";
     char *p = "abc***de";
	Solution s1;
	bool f = s1.isMatch(s, p);
	cout << f << endl;
}

改进:提交结果:accepted

思路还是跟上面的算法思想是一样的 ,见:isMatch2(),

描述:对于p = "c*ab*c",我们可以猜想出它可以匹配的s应该长成这样: "c....ab.....c",省略号表示0到任意多的字符。我们发现主要就是p的中间那个"ab"比较麻烦,一定要s中的'ab'来匹配,因此只要s中间存在一个"ab",那么一切都可以交给后面的'*'了。

所以说,当我们挨个比较p和s上的字符时,当我们遇到p的第一个'*',我们实际只需要不断地在s的剩余部分找和'ab'匹配的部分。

换言之,我们可以记录下遇到*时p和s的位置,记为presp和press,然后挨个继续比较*(++p)和*(++s);如果发现*p != *s,就回溯回去,p = presp,s = press+1, ++press;直到比较到末尾,或者遇到了下一个'*',如果遇到了下一个'*',说明 "ab"部分搞定了,下面的就交给第二个'*'了;如果p和s都到末尾了,那么就返回true;如果到末尾了既没遇到新的'*',又还存在不匹配的值,press也已经到末尾了,那么就返回false了。

#include<iostream>
#include<time.h>
using namespace std;

class Solution {
public:
	bool isMatch(const char *s, const char *p) {
		// 递归方法:time limit exceeded
		if (*s == '\0')
		{
			if (*p == '\0')
				return true;
			if (*p != '*') return false;
		}
		if (*s == *p || *p == '?')
			return isMatch(++s, ++p);
		else if (*p == '*')
		{
			while (*(++p) == '*');
			for (; *s != '\0'; s++)
			if (isMatch(s, p))
				return true;
			return false;
		}
		else
			return false;
	}
	bool isMatch2(const char *s, const char *p) {
		// accepted
		bool startFound = false;
		const char *pre_s = NULL;
		const char *pre_p = NULL;
		int pLen = 0;
		while (*s != '\0')
		{
			if (*s == *p || *p == '?')
			{
				s++; p++;
			}
			else if (*p == '*')
			{
				startFound = true;
				pre_s = s;
				pre_p = ++p;
			}

			else if (startFound == true && *s != *p)
			{
				s = ++pre_s;
				p = pre_p;
			}
			else
				return false;
		}
		while (*p == '*') p++;
		return *p == '\0';
	}
};
void main()
{
	char *s = "abbaabbbbababaababababbabbbaaaabbbbaaabbbabaabbbbbabbbbabbabbaaabaaaabbbbbbaaabbabbbbababbbaaabbabbabb";
	char *p = "***b**a*a*b***b*a*b*bbb**baa*bba**b**bb***b*a*aab*a**";
	Solution s1;
	clock_t start = 0, end = 0;
	start = clock();
	//bool f = s1.isMatch(s, p);
	bool f = s1.isMatch(s, p);
	end = clock();
	cout << "总的运行时间是:" << (double)(end - start) ;
	cout << f << endl;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值