本题,其实和分苹果的题有那么一丢丢的类似,在此提供两种能通过的解法(主要就是对于‘*’的处理)
1.这种解法其实是错误的,但是也要说说他的思路,对于 ‘*’ 他直接找 ‘*’ 下一个字符是否出现在需要匹配的串中,并且找到那个位置,认为此位置到之前就是‘*’所匹配的内容。
但是这种解法是错误的,在此给出一个测试用例
J*Smi??
JhonSSmith
至于为什么他能通过,oj太烂被!
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str1, str2;
int i, j,len1,len2;
cin >> str1 >> str2;
len1 = str1.size();
len2 = str2.size();
i = j = 0;
while (i < len1&&j < len2)
{
if (str1[i] == '?')
{
i++;
j++;
}
else if (str1[i] == '*')
{
i++;
j=str2.find(str1[i], j);//这就是我上面思路中的关键语句
if (j == string::npos)
{
j = len2;
}
}
else
{
if (str1[i] == str2[j])
{
i++;
j++;
}
else
{
cout << "false";
return 0;
}
}
}
if (i == len1 && j == len2)
cout << "true";
else
cout << "false";
return 0;
}
2.这种提供的方法,我认为是标准的解法,先看代码,再解释
#include <iostream>
using namespace std;
bool ISMatch(char *s1, char *s2, int p, int q)
{
if (p<0 && q<0)
{
return true;
}
if (p<0 || q<0)
{
return false;
}
if (s1[p] == '*')
{
return ISMatch(s1, s2, p-1, q) || ISMatch(s1, s2, p, q-1);
}
if (s1[p] == s2[q] || s1[p] == '?')
{
return ISMatch(s1, s2, p-1, q-1);
}
return false;
}
int main()
{
char inStr[30];
char matchStr[30];
bool ret;
gets_s(inStr);
gets_s(matchStr);
if (inStr == NULL || matchStr == NULL)
{
cout << "false" << endl;
return 0;
}
ret = ISMatch(inStr, matchStr, strlen(inStr) - 1, strlen(matchStr) - 1);
if (ret)
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
return 0;
}
解释:对于 ‘*’ 的处理,要么匹配0次,对应语句ISMatch(s1,s2,p-1,q),要么匹配多次ISMatch(s1,s2,p,q-1),对于递归截止条件,只有当p和q同时小于0,即都匹配完成时才算匹配成功!