44. 通配符匹配

给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。

'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。
两个字符串完全匹配才算匹配成功。

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。
示例 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:

输入:
s = "aa"
p = "*"
输出: true
解释: '*' 可以匹配任意字符串。
示例 3:

输入:
s = "cb"
p = "?a"
输出: false
解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。
示例 4:

输入:
s = "adceb"
p = "*a*b"
输出: true
解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".
示例 5:

输入:
s = "acdcb"
p = "a*c?b"
输出: false

#include<iostream>
#include<stack>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;

/*
对于星号的处理,可以匹配任意字符串,简直像开了挂一样,
就是说在星号对应位置之前,不管你s中有任何字符串,
我大星号都能匹配你,那就是一旦p中有s中不存在的字符,
那么一定无法匹配,因为星号只能增加字符,不能消除字符,
再有就是星号一旦确定了要匹配的字符串,
对于星号位置后面的匹配情况也就鞭长莫及了。
所以p串中星号的位置很重要,用 jStart 来表示,
还有星号匹配到s串中的位置,使用 iStart 来表示,
这里 iStart 和 jStart 均初始化为 -1,表示默认情况下是没有星号的。
然后再用两个变量i和j分别指向当前s串和p串中遍历到的位置。
开始进行匹配,若i小于s串的长度,进行 while 循环。
若当前两个字符相等,或着p中的字符是问号,
则i和j分别加1。若 p[j] 是星号,要记录星号的位置,
jStar 赋为j,此时j再自增1,iStar 赋为i。
若当前 p[j] 不是星号,并且不能跟 p[i] 匹配上,
此时就要靠星号了,若之前星号没出现过,
那么就直接跪,比如 s = "aa" 和 p = "c*",
此时 s[0] 和 p[0] 无法匹配,虽然 p[1] 是星号,
但还是跪。如果星号之前出现过,可以强行续一波命,
比如 s = "aa" 和 p = "*c",当发现 s[1] 和 p[1] 无法匹配时,
但是好在之前 p[0] 出现了星号,把 s[1] 交给 p[0] 的星号去匹配。
至于如何知道之前有没有星号,这时就能看出 iStar 的作用了,
因为其初始化为 -1,而遇到星号时,其就会被更新为i,
只要检测 iStar 的值,就能知道是否可以使用星号续命。
虽然成功续了命,匹配完了s中的所有字符,但是之后还要检查p串,
此时没匹配完的p串里只能剩星号,不能有其他的字符,将连续的星号过滤掉,
如果j不等于p的长度,则返回 false
*/


class Solution {
public:
	bool isMatch(string s, string p) {
		int i = 0, j = 0, iStart = -1, jStart = -1, m = s.size(), n = p.size();
		while (i < m) 
		{
			if (j < n && (s[i] == p[j] || p[j] == '?')) 
			{
				++i; ++j;
			}
			else if (j < n && p[j] == '*') 
			{
				iStart = i;
				jStart = j++;
			}
			else if (iStart >= 0)
			{
				i = ++iStart;
				j = jStart + 1;
			}
			else
			{
				return false;
			}
		}
		while (j < n && p[j] == '*')
		{
			++j;
		}
		return j == n;
	}
};
int main()
{
	string s1;
	string s2;
	bool ans;
	getline(cin, s1);
	getline(cin, s2);
	ans = Solution().isMatch(s1, s2);
	cout << ans << endl;
	system("pause");
	return 0;
}

  

原文地址:https://www.cnblogs.com/277223178dudu/p/14924817.html