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;
}