题目描述
有两个字符构成的环。请写一个程序,计算这两个字符环上最长公共字符串的长度。例如,字符串“ABCEFAGADEGKABUVKLM”的首尾连在一起,构成一个环;字符串“MADJKLUVKL”的首尾连在一起,构成一个另一个环;“UVKLMA”是这两个环的一个公共字符串。
输入
若干行,每行包括两个不包含空格的字符串。这两个字符串用空格分开。若其中某个字符串的长度为1,则表示结束。否则,每个字符串的首尾相连即为一个环。每个环上字符总数不超过255。
输出
为每行输入,分别输出一个整数,表示这两个字符环上最长公共字符串的长度。最后一行没有输出。
样例输入
ABCEFA24*92(GADEGKABUVKLM AD&30ijJKLAaUVKLM
313435t974 008bac
A 33
样例输出
6
0
题解
首先看到这一题会发现数据大小为255,一个很小的数据,自然想到暴力
字符串为“环状”,遍历要按照“环状”遍历
输入的某个字符串长度为1便结束,按照oj特点,只要输入到文件结束即可,可以采取~scanf的输入方式,也可以使用判断条件,自由选择
思路
对于两个字符串,为了方便进行遍历,这里选择比较两个字符串的长度,以字符串长的字符串作为被比较对象,依次遍历,当在较小的字符串中找到被比较的字符,开始依次往后计数,并且取最大的长度返回。
注意一点,字符环代表结束的标志不是最后一个字符,是开始计数的字符的上一个字符
下面是代码
#include<stdio.h>
#include<string.h>
char a[300], b[300];//两个字符串
int len = 0;//最长的公共子串长度
int num1, num2;//两个字符串的长度
int loop(int step, int num, int itemp) {
//step用来记录被比较字符的位置,num为较短字符串的长度,itemp用来表示字符串不同的长度时的情况
int i,j;
int count = 0;//记录子串的长度
if (itemp == 2) {
if (step == num1) return len;//当被比较字符到达末尾时,递归结束,返回最大子串长度
for (i = 0; i < num; i++) {
if (b[i] == a[step]) {//寻找计数开始点
count = 0;//重置计数
j = i;
int h=0;
while (b[j] == a[step + h]||j==i-1) {
count++;
j++;
h++;
if (j == num) j = 0;//当较小子串搜索到达末尾,继续从第一个字符开始计数
if(step+h==num1) h=-step;//当较大子串搜索到达末尾,继续从第一个字符开始计数
}
if (len < count) len = count;//比较取最大子串长度
}
}
loop(step + 1, num, itemp);//被比较字符位置向后推1
}
else {//第二种情况,与上述代码意思相同
if (step == num2) return len;
for (i = 0; i < num; i++) {
if (a[i] == b[step]) {
count = 0;
j = i;
int h=0;
while (a[j] == b[step + h]||j==i-1) {
count++;
j++;
h++;
if (j == num) j = 0;
if(step+h==num2) h=-step;
}
if (len < count) len = count;
}
}
loop(step + 1, num, itemp);
}
}
int main() {
int i;
while (~scanf("%s%s",a,b)) {//不断输入直到文件末尾
len=0;
num1 = strlen(a);
num2 = strlen(b);
if (num1 >= num2) {
for (i = 0; i < num2; i++) {
}
loop(0, num2, 2);
}
else
loop(0, num1, 1);
printf("%d\n", len);//输出最大子串
}
return 0;
}