192. 通配符匹配
判断两个可能包含通配符“?”和“*”的字符串是否匹配。匹配规则如下:
'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。
两个串完全匹配才算匹配成功。
样例
样例1
输入:
"aa"
"a"
输出: false
输出2
输入:
"aa"
"aa"
输出: true
输出3
输入:
"aaa"
"aa"
输出: false
输出4
输入:
"aa"
"*"
输出: true
说明: '*' 可以替换任何字符串
输出5
输入:
"aa"
"a*"
输出: true
样例6
输入:
"ab"
"?*"
输出: true
说明: '?' -> 'a' '*' -> 'b'
样例7
输入:
"aab"
"c*a*b"
输出: false
注意事项
1<=|s|, |p| <= 1000
s仅包含小写英文字母
p包含小写英文字母,?和 *
bool find(int start,std::string &targetStr, std::string &firstStr,std::vector<bool> &visitedVec, std::stack<int> &pIntStk)
{
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
int tSize = targetStr.size();
bool bFind = false;
int retPosition = 0;
int k = 0;
for (; k < tSize && start < firstStr.size();)
{
int tmpBegin = start;
while (targetStr[k] == '?' || targetStr[k] == firstStr[tmpBegin])
{
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
k++; tmpBegin++;
if (k >= tSize)
{
break;
}
else if (tmpBegin >= firstStr.size())
{
return false;
}
}
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
if (k >= tSize && tmpBegin <= firstStr.size())
{
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
bFind = true;
start = tmpBegin;
break;
}
start++;
k = 0;
}
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
if (true == bFind)
{
retPosition = start - tSize;
if (false == visitedVec[retPosition]) //如果找到,插入栈
{
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
pIntStk.push(retPosition);//保存开始位置
visitedVec[retPosition] = true;
return true;
}
}
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
return false;
}
bool func2(string &firstStr, string &secondStr, std::vector<std::string> &pStrVec, std::stack<int> &pIntStk, std::vector<bool> &visitedVec,int start)
{
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
if (pStrVec.empty())
{
int i = 0;
int j = 0;
while (i < firstStr.size() && j < secondStr.size())
{
if (firstStr[i] == secondStr[j] || '?' == secondStr[j])
{
i++;
j++;
if (i == firstStr.size()-1&& j == secondStr.size() - 1 && (firstStr[i] == secondStr[j] || '?' == secondStr[j]))
{
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
return true;
}
}
else
{
return false;
}
}
if (i < firstStr.size() || j < secondStr.size())
{
return false;
}
}
//结束条件,一个是失败结束,无法找在第一行找到第一个,一个是成功结束,在第一行找到所有
if (pIntStk.empty())
{
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
std::string targetStr = pStrVec[0];
bool bFind = find(start, targetStr, firstStr, visitedVec, pIntStk);//如果找到,插入栈
if (false == bFind)
{
return false;
}
else
{
//找到第一个
int top = pIntStk.top();
if (top != 0 && secondStr[0] != '*')
{
return false;
}
}
}
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
if (pIntStk.size() == pStrVec.size())
{
std::cout<<__FUNCTION__<<","<<__LINE__<<std::endl;
int top = pIntStk.top();
if ('*' == secondStr[secondStr.size() - 1])//第二行最后一个是*
{
return true;
}
else if (top + pStrVec[pIntStk.size() - 1].size() == firstStr.size()) //栈运行到第一行最后一个
{
return true;
}
}
//是否访问过,不断递归下去
if (!pIntStk.empty())
{
int top = pIntStk.top();
if (pIntStk.size() == pStrVec.size())//栈满
{
pIntStk.pop();
}
int stkSize = pIntStk.size();
std::string targetStr = "";
if (stkSize< pStrVec.size())
{
targetStr = pStrVec[stkSize];
if (stkSize == 0)
{
start = top + pStrVec[0].size();//开始位置,加上本身长度
}
else
{
start = top + pStrVec[stkSize - 1].size();//开始位置,加上本身长度
}
bool bFind = find(start, targetStr, firstStr, visitedVec, pIntStk);
if (false == bFind )
{
//弹出
pIntStk.pop();
}
return func2(firstStr, secondStr, pStrVec, pIntStk, visitedVec, start);
}
}
}
bool isMatch(string &s, string &p) {
// write your code here
int sSize = s.size();
int pSize = p.size();
int is = 0;
int ip = 0;
std::vector<std::string> pStrVec;
std::stack<int> pIntStk;
std::vector<bool> visitedVec(sSize,false);
while (ip<pSize)
{
int front = ip;
bool bFind = false;
if (ip < pSize && p[ip] == '*')
{
bFind = true;
while (ip < pSize && p[ip] == '*')
{
ip++;
}
front = ip;
}
if (ip >= pSize)
{
break;
}
int back = ip ;
if (ip < pSize && p[ip] != '*')
{
while (ip < pSize && p[ip] != '*')
{
ip++;
}
if (ip < pSize && p[ip] == '*')
{
bFind = true;
}
back = ip - 1;
}
if (true == bFind)
{
std::string tmp = p.substr(front, back - front + 1);
pStrVec.push_back(tmp);
}
}
if(0 ==pStrVec.size())
{
if(pSize>0)
{
if(p[0] == '*')
{
return true;
}
}
else if(sSize ==0)
{
return true;
}
}
return func2(s,p,pStrVec,pIntStk,visitedVec,0);
}