Implement wildcard pattern matching with support for ‘?’ and ‘*’.
‘?’ 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
下面提供三种解法,第一种时间复杂度没过关,但是容易理解,第二种为迭代法,第三种为动态规划。
bool WildcardMatching::isMatch1(string s, string p)
{
int i = 0;
for (; i < s.length(); i++)
{
//迭代法
if (p[i] == '?')
{
return isMatch1(s.substr(i + 1), p.substr(i + 1));
}
else if (p[i] == '*')
{
//‘*’可以代表任意长度的字符串
return isMatch1(s.substr(i + 1), p.substr(i)) || isMatch1(s.substr(i), p.substr(i + 1));
}
else if (p[i] != s[i])
{
return false;
}
}
string s1 = s.substr(i);
//这里需要注意下,p的末尾可能为*
while (i < p.length() && p[i] == '*') i++;
string p1 = p.substr(i);
if (s1 != p1) return false;
return true;
}
bool WildcardMatching::isMatch2(string s, string p)
{
int slen = s.size(), plen = p.size(), i, j, iStar = -1, jStar = -1;
for (i = 0, j = 0; i<slen; ++i, ++j)
{
if (p[j] == '*')
{ //meet a new '*', update traceback i/j info
iStar = i;
jStar = j;
--i;
}
else
{
if (p[j] != s[i] && p[j] != '?')
{ // mismatch happens
if (iStar >= 0)
{ // met a '*' before, then do traceback
i = iStar++;
j = jStar;
}
else return false; // otherwise fail
}
}
}
while (p[j] == '*') ++j;
return j == plen;
}
//DP算法
bool WildcardMatching::isMatch3(string s, string p)
{
int m = s.length();
int n = p.length();
//dp[i][j]表示s[0, i) 与 p[0, j)是否匹配
//首先创建个bool类型的二维数组保存结果
bool** dp = new bool*[m + 1];
for (int i = 0; i < m + 1; i++)
dp[i] = new bool[n + 1];
dp[0][0] = true;
for (int j = 1; j <= n; j++)
dp[0][j] = dp[0][j - 1] && p[j - 1] == '*';
for (int i = 1; i <= m; i++)
dp[i][0] = false;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (p[j - 1] == '*')
{
//考虑'*'表示空字符或者单个字符的情况
dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
}
else
{
//非空情况的匹配
dp[i][j] = dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '?');
}
}
}
return dp[m][n];
}