string:通配符匹配

LeetCode, Wildcard Matching

#include <iostream>
#include <vector>
using namespace std;

//动态规划
bool solution(const char *s, const char* p)
{
	vector<vector<bool>> vec( strlen(s) + 1, vector<bool>(strlen(p) + 1, false) );
	vec[0][0] = true;
	for ( int j = 1; j < vec[0].size(); ++j)
	{
		if (p[j - 1] == '*') 
		{
			vec[0][j] = vec[0][j - 1];
		}
	}

	for (int i = 1; i < vec.size(); ++i  )
	{
		for ( int j = 1; j < vec[i].size(); ++j )
		{
			if( s[i - 1] == p[j - 1] || (p[j - 1] == '?' && s[i - 1] != '\0' ))
			{ 
				vec[i][j] = vec[i - 1][j - 1];
			}
			else if ( p[j - 1] == '*' )
			{
				//vec[i - 1][j] *代表空字符 ab,ab*
				//vec[i][j - 1] *代表非空字符 abcd,ab*
				vec[i][j] = vec[i - 1][j] || vec[i][j - 1];
			}
		}
	}

#if 0
	for (int j = 1; j < vec[0].size(); ++j)
	{
		for (int i = 1; i < vec.size(); ++i)
		{
			cout << vec[i][j] << '\t';
		}
		cout << endl;
	}
#endif // 0
	return vec[strlen(s)][strlen(p)];
}

//递归版 时间复杂度O(n!*m!),空间复杂度O(n)
//主要是*的匹配问题,p没遇到一个*,就保留当前*的坐标和s的坐标,然后s从前往后扫描,如果不成功,则s++,重新扫描
bool solution2( const char *s, const char *p)
{
	if ( *p == '*' ) 
	{
		while (*p == '*') ++p; //skip continuous *
		if (*p == '\0') return true;
		while (*s != '\0' && !solution2(s, p)) ++s;

		return *s != '\0';
	}
	else if (*p == '\0' || *s == '\0') return *p == *s;
	else if (*p == *s) return solution2(++s, ++p);
	else return false;
}

//迭代版 时间复杂度O(n*m),空间复杂度O(1)
bool solution3(const char *s, const char *p)
{
	bool star = false;
	const char *str, *ptr;
	for ( str = s, ptr = p; *str != '\0'; ++str, ++ptr)
	{
		switch (*ptr)
		{
		case '?':
			break;
		case '*':
			star = true;
			s = str, p = ptr;
			while (*p == '*') ++p;
			if (*p == '\0') return true;
			str = s - 1;
			ptr = p - 1;
			break;
		default:
			if (*str != *ptr)
			{
				//如果前面没有*,则匹配不成功
				if (!star) return false;
				++s;
				str = s - 1;
				ptr = p - 1;
			}
		}
	}
	while (*ptr == '*') ++ptr;
	return (*ptr == '\0');
}

int main()
{
	//cout << solution("adceb", "*a*b");
	//solution("adceb", "*a*b");
	//cout << solution2("adceb", "*a*b");
	cout << solution3("adceb", "*a*b");

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值