1077 Kuchiguse这道题,简而言之就是对输入的N个字符串求它们的最大公共后缀,如果这个最大公共后缀不存在,就输出“nai”。
首先需要把N个字符串录入到字符数组里面,这里使用二维的字符数组作为存储结构。
char str[100][256];
挑选第一个字符串的尾字符逐一与余下字符串的尾字符比对,只要有一个不匹配,就说明没有公共后缀,如果尾字符都匹配通过,那么需要一个变量count来记录第一次的通过(最后需要输入公共后缀,所以需要知道这个公共后缀的长度);然后将第一个字符串的倒数第二个字符逐一与余下字符串的倒数第二个字符比对,全部通过count加一……以此类推。
但是在这一过程中存在一些问题,第一,在上述的比对过程中存在着数组越界的危险,当某个字符串本身就是公共后缀时,再下一步的比对会造成数组越界,所以我们必须要知道最短的字符串的长度,在这个长度范围内进行比对。第二,当我们比对时,总是从最后一个字符开始,但是每个字符串的长度不一定都一样,又因为每次取一个字符与其他字符串的字符进行比对,所以要么花费空间将每个字符串的长度都储存下来,要么花费时间每次循环都进行长度的求取。其实可以一开始就将字符串反转过来(Hello 转为 olleH),这样就将问题转为求公共前缀,字符都是从数组下标0开始的,也符合一般人的思考方式,简化了题目。
具体代码如下:
#include<cstdio>
#include<cstring>
int n, minLen = 256, count = 0;//minLen储存最短的字符串的长度,count储存公共后缀的长度
char s[100][256];
void inversion(char str[],int len)//字符串反转
{
for(int i = 0;i < len/2;i++)
{
char temp = str[i];
str[i] = str[len-i-1];
str[len-i-1] = temp;
}
}
int main()
{
if(scanf("%d",&n));
getchar();
for(int i = 0;i < n;i++)
{
if(scanf("%[^\n]",s[i]));
getchar();
int len = strlen(s[i]);
if(len<minLen) minLen = len;
inversion(s[i],len);
}
for(int i = 0;i < minLen;i++)
{
char c = s[0][i];
bool same = true;
for(int j = 1;j < n;j++)
{
if(s[j][i] != c)
{
same = false;
break;
}
}
if(same) count++;
else break;
}
if(count)
{
for(int i = count-1;i >= 0;i--)
{
printf("%c",s[0][i]);
}
}
else printf("nai");
return 0;
}
PAT测试里面不能使用gets(),所以使用scanf("%[^\n]",另外需要getchar()将缓存中的换行读掉(scanf不读取换行),以上。