【编程|20分】字符串匹配问题
时间限制:C/C++2秒,其他语言4秒
空间限制:C/C++262144K,其他语言524288K
64bit IO Format:%lld
题目描述:
对于字符串str,其中绝对不含有字符’.’和’’。再给定字符串exp,其中可以含有’.’或’’,’’字符不能是exp的首字符,并且任意两个’’字符不相邻。exp中的’.’代表任何一个字符,exp中的’’表示’’的前一个字符可以有0个或者多个。请写一个函数,判断str是否能被exp匹配(注意:输入的数据不保证合法,但只含小写字母和’.’和’*’)
输入描述:
输入包含两行,两个字符串,分别代表str和exp(1≤lengthexp,lengthstr≤300)。
输出描述:
如果str是能被exp匹配,请输出“YES”,否则输出“NO”。
示例1(输入输出示例仅供调试,后台判题数据一般不包含示例)
输入:
abc
abc
输出
YES
示例2(输入输出示例仅供调试,后台判题数据一般不包含示例)
输入
abcd
.*
输出
YES
备注:
时间复杂度O(n2*m),额外空间复杂度O(n2),(n为字符串str长度,m为字符串exp长度)
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char str1[310], str2[310];
int dp[310][310];
int main()
{
while (~scanf("%s %s", str1 + 1,str2 + 1))
{
fill(dp[0], dp[0] + 310 * 310, 0);
int len1 = int(strlen(str1 + 1));
int len2 = int(strlen(str2 + 1));
int flag = 0;
for (int i = 1; i <= len2; ++i)
{
if (str2[i] == '*' && (str2[i + 1] == '*' || i == 1))
{
printf("NO\n");
flag = 1;
break;
}
}
if (flag == 1)
return 0;
for (int i = 0; i <= len1; ++i)
{
for (int j = 0; j <= len2; ++j)
{
if (i == 0 && j == 0)
{
dp[i][j] = 1;
continue;
}
if (i > 0 && j == 0)
{
dp[i][j] = 0;
continue;
}
if (str2[j] != '*')
{
if (i == 0)
continue;
if (str1[i] == str2[j] || str2[j] == '.')
{
dp[i][j] = dp[i - 1][j - 1];
}
}
else
{
if (i == 0 || str1[i] != str2[j - 1] && str2[j - 1] != '.')
{
if (j >= 2)
dp[i][j] = dp[i][j - 2];
}
else
dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i - 1][j];
}
}
}
if (len1 < 310 && len2 < 310 && len1 >= 0 && len2 >= 0 && dp[len1][len2] == 1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
在VS2019下,需要对scanf做一些修改:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char str1[310], str2[310];
int dp[310][310];
int main()
{
while (~scanf_s("%s %s", str1 + 1, 310, str2 + 1, 310))
{
fill(dp[0], dp[0] + 310 * 310, 0);
int len1 = int(strlen(str1 + 1));
int len2 = int(strlen(str2 + 1));
int flag = 0;
for (int i = 1; i <= len2; ++i)
{
if (str2[i] == '*' && (str2[i + 1] == '*' || i == 1))
{
printf("NO\n");
flag = 1;
break;
}
}
if (flag == 1)
return 0;
for (int i = 0; i <= len1; ++i)
{
for (int j = 0; j <= len2; ++j)
{
if (i == 0 && j == 0)
{
dp[i][j] = 1;
continue;
}
if (i > 0 && j == 0)
{
dp[i][j] = 0;
continue;
}
if (str2[j] != '*')
{
if (i == 0)
continue;
if (str1[i] == str2[j] || str2[j] == '.')
{
dp[i][j] = dp[i - 1][j - 1];
}
}
else
{
if (i == 0 || str1[i] != str2[j - 1] && str2[j - 1] != '.')
{
if (j >= 2)
dp[i][j] = dp[i][j - 2];
}
else
dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i - 1][j];
}
}
}
if (len1 < 310 && len2 < 310 && len1 >= 0 && len2 >= 0 && dp[len1][len2] == 1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
第七题,在DEV-C++5.11中,输入数据,再按回车无结果。正确方法是输入数据,按回车,再按CTRL+Z,再按回车,最后才会产生结果。在VS2019中,输入数据,再按回车无结果。正确方法是输入数据,按回车,再按CTRL+C,最后才会产生结果。