Leetcode Wildcard Matching 字符串*?模式匹配

大数据的测试样例是非常偷懒的一串aaaaaaaaaaaaaaaaaaa,所以采用回溯的方法与常见的字符串快速寻找字串的算法效率几乎一样。例如sunday算法的最坏效率是O(m*n),但它的常见效率高达O(m+n)。


应用例如KMP、Sunday算法到一个可变的模式串p中,我稍微动了点儿脑筋。

本人代码比较冗长,各位看官忍忍……

分享如下:

采用回溯,140ms通过OJ的测试。

class Solution
{
public:
	int slen;
	int plen;

	bool isMatch(const char *s, const char *p)
	{
		slen = strlen(s);
		plen = strlen(p);
		int curs = 0;
		int curp = 0;
		int lastPos = 0;
		bool skip = false;
		bool match = true;
		while (true)
		{
			if (p[curp] == '*')
			{
				skip = true;
				curp++;
				lastPos = curp;
				//goto loopstart;
				continue;
			}
			if (s[curs] == '\0')//will return
			{
				while (p[curp] == '*')
				{
					curp++;
				}
				if (p[curp] != '\0')
					return false;
				return true;
			}
			if (p[curp] == '\0')//will return
			{
				if (!skip)
					return false;
				if (!match)
					return false;
				int stemp = slen - 1;
				for (int j = curp - 1; j >= lastPos; j--)
				{
					if (p[j] != s[stemp]&&p[j]!='?')
						return false;
					stemp--;
				}
				return true;
			}
		
			if (p[curp] != s[curs] && p[curp] != '?')//mismatch, move curp to lastPos, move curs forward/backward
			{
				if (!skip)
					return false;
				curs -= (curp - lastPos - 1);
				match = false;
				curp = lastPos;
			}
			else
			{
				match = true;
				curs++;
				curp++;
			}
		}
	}
};


采用Sunday,128ms通过测试

请不要在意goto语句…

class Solution
{
public:
	int slen;
	int plen;

	bool isMatch(const char *s, const char *p)
	{
		slen = strlen(s);
		plen = strlen(p);
		int curs = 0;
		int curp = 0;
		int lastPos = 0;
		bool skip = false;
		bool match = true;
	loopstart:
		int table[128];
		memset(table, -1, sizeof(table));
		while (true)
		{
			//if (curs>=slen) //never happens
			if (p[curp] == '*')
			{
				skip = true;
				curp++;
				lastPos = curp;
				goto loopstart;
				//continue;
			}
			if (s[curs] == '\0')//will return
			{
				while (p[curp] == '*')
				{
					curp++;
				}
				if (p[curp] != '\0')
					return false;
				return true;
			}
			if (p[curp] == '\0')//will return
			{
				if (!skip)
					return false;
				if (!match)
					return false;
				int stemp = slen - 1;
				for (int j = curp - 1; j >= lastPos; j--)
				{
					if (p[j] != s[stemp] && p[j] != '?')
						return false;
					stemp--;
				}
				return true;
			}
			//p is not '*', p and s are not end
			table[p[curp]] = curp - lastPos;

			if (p[curp] != s[curs] && p[curp] != '?')//mismatch, move curp to lastPos, move curs forward/backward
			{
				if (!skip)
					return false;
				if (s[curs + 1] == '\0')
					curs++;
				else if (table[s[curs + 1]]==-1&&table['?'] != -1)
					curs -= (table['?'] - 1);
				else
					curs -= (table[s[curs + 1]] - 1);
				curp = lastPos;
				match = false;
				goto loopstart;
				//curs -= (curp - lastPos - 1);
				//match = false;
				//curp = lastPos;
			}
			else
			{
				match = true;
				curs++;
				curp++;
			}
		}
	}
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值