此题的难点就是思路问题,本质就是分别找两个字符串公共的最长前后缀。
将第一人说的话定位字符串s,另一人说的话定为字符串p。
既然找最大公共前后缀那么应该从p字符串的末尾开始与s字符串开始匹配,避免出现找到的不是最长公共前后缀。如果不相等,则将p字符串指针前移一位,若相等,将s与p字符串都向前移一位。
题目说明:小CC最喜欢的就是接话茬,别人说一句,小CC就会接着他的话尾巴继续说下去,然后告诉他这是“顶针”修辞手法,活活将人气死。小XX也喜欢接话茬,每天都要与小CC比较技艺。然而无论是谁,都会被他们活活气死,因此两人总是难决胜负。后来小CC和小XX一起上了厦门大学,学习了校选课《接话茬数学原理与杠精的自我修养》,他们决定对两人的接话茬水平进行定量评估。
他们约定比赛规则如下,随机找一个倒霉的路人,路人说一句话,他们一起来接,他们接的话的前缀可以作为路人说的话后缀的长度就是那句话的水平。比如,别人说“abbbaabbc”,小CC接了一句“abbcefagd”,他所说的话的前缀“abbc”正是路人所说的话的后缀,长度为4,那么小CC的水平就是4;如果小XX说的是“xbbcadf”,无法构成路人所说的话的后缀,因此水平只有0。
现在,他们的比赛正式开始,由你来写一个程序充当裁判。
输入格式:
共三行,每行是一句话,长度均不超过106。
第一行是路人说的话。第二行是小CC说的话。第三行是小XX说的话。
输出格式:
仅一行,输出小CC和小XX接的话的水平,以空格分割,行末没有多余空格,以换行结束。
输入样例:
abbaabbc
abbc
xbb
*
输出样例:
4 0
实现代码
#include<iostream>
#include<string.h>
using namespace std;
int find(char* s, char* p)
{
int l,m,i,k,j;
l = strlen(s);
l--;
m = strlen(p);
for (i = m-1; i>=0;)
{
if (s[l] != p[i])//如果不相等,则将p字符串指针前移一位再次进行比较
i--;
else
{
k = i; j = l;//将当前的字符串长度保留,声明新变量
while (k >= 0)
{
if (s[j] == p[k])
{
j--; k--;//如果相等则字符串s,p都前移一位
if (j < 0 && k >= 0)//如果此时字符串s已经到头,那么p字符串指针前移一位进行比较
{
i--;
break;
}
}
else//如不相等,p字符串指针前移一位进行比较
{
i--;
break;
}
}
if (k == -1)//如果k=-1则说明找到了最大的公共字符串
return i+1;
}
}
return 0;//如果没找到则为0
}
int main()
{
char s[1000001], p1[1000001], p2[1000001];
cin >> s >> p1 >> p2;
int m, n;
m = find(s, p1);
n = find(s, p2);
cout << m << " " << n;
return 0;
}