在USTCOJ的1324这道题中,当遇到tttttt tttttt tttttttttttt这样的输入实例时,如下伪代码片段效率非常低。因为有很多的重复计算在里面。可通过存储match函数调用结果减少重复计算。
int match(char *a, char *b, char *c)
{
if *c = 0
return 1
if *a = *b = *c
return match(a+1, b, c+1) || match(a, b+1, c+1)
if *a = *c
return match(a+1, b, c+1)
if *b = *c
return match(a, b+1, c+1)
return 0
}
其中代码一是用数组来存储结果,代码二用stl里面的set存储参数对(pair)。代码中while循环的目的是为了减少递归层次,仅当不能判断应该从哪一个子串(a或/和b)中取字符到主串(c)时,才跳出循环开始递归操作。
代码一:
#include <cstdio>
#include <cstring>
#include <set>
#include <utility>
#define N 500
using namespace std;
char flag[N][N];
char stra[N], strb[N], strc[2*N];
int match(char *a, char *b, char *c)
{
while (*a || *b)
{
if(*c != *a && *c != *b)
return 0;
if(*a == *b)
break;
else
{
if (*a == *c)
a++, c++;
else
b++, c++;
}
}
//此时*a == *c,所以两重递归
if (*a)
{
if (flag[a+1-stra][b-strb] == 0)
{
if (match(a+1, b, c+1))
return 1;
else
flag[a+1-stra][b-strb] = 1;
}
if (flag[a-stra][b+1-strb] == 0)
{
if (match(a, b+1, c+1))
return 1;
else
flag[a-stra][b+1-strb] = 1;
}
return 0;
}
//若*a == '\0',表示a、b字符串中的字符均已在c中匹配,故返回匹配成功
else
return 1;
}
int main()
{
freopen("1324.in", "r", stdin);
freopen("1324.out", "w", stdout);
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
memset(&flag[0][0], 0, N*N*sizeof(flag[0][0]));
scanf("%s%s%s", stra, strb, strc);
if (match(stra, strb, strc))
printf("Data set %d: yes\n", i);
else
printf("Data set %d: no\n", i);
}
return 0;
}
代码二:
#include <cstdio>
#include <cstring>
#include <set>
#include <utility>
using namespace std;
typedef pair<char *, char *> MyType;
set<MyType> dpresult;
int match(char *a, char *b, char *c)
{
while (*a || *b)
{
if(*c != *a && *c != *b)
return 0;
if(*a == *b)
break;
else
{
if (*a == *c)
a++, c++;
else
b++, c++;
}
}
//此时*a == *c,所以两重递归
if (*a)
{
MyType p(a+1, c+1);
if (dpresult.find(p) == dpresult.end())
{
if (match(a+1, b, c+1))
return 1;
else
dpresult.insert(p);
}
p.first = b+1;
if (dpresult.find(p) == dpresult.end())
{
if (match(a, b+1, c+1))
return 1;
else
dpresult.insert(p);
}
return 0;
}
//若*a == '\0',表示a、b字符串中的字符均已在c中匹配,故返回匹配成功
else
return 1;
}
int main()
{
freopen("1324.in", "r", stdin);
freopen("1324.out", "w", stdout);
char a[500], b[500], c[1000];
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
dpresult.clear();
scanf("%s%s%s", a, b, c);
if (match(a, b, c))
printf("Data set %d: yes\n", i);
else
printf("Data set %d: no\n", i);
}
return 0;
}