问题描述
The Japanese language is notorious for its sentence ending particles. Personal preference of such particles can be considered as a reflection of the speaker’s personality. Such a preference is called “Kuchiguse” and is often exaggerated artistically in Anime and Manga. For example, the artificial sentence ending particle “nyan~” is often used as a stereotype for characters with a cat-like personality:
-
Itai nyan~ (It hurts, nyan~)
-
Ninjin wa iyada nyan~ (I hate carrots, nyan~)
Now given a few lines spoken by the same character, can you find her Kuchiguse?
输入格式
Each input file contains one test case. For each case, the first line is an integer N (2 ≤ N ≤ 100). Following are N file lines of 0~256 (inclusive) characters in length, each representing a character’s spoken line. The spoken lines are case sensitive.
输出格式
For each test case, print in one line the kuchiguse of the character, i.e., the longest common suffix of all N lines. If there is no such suffix, write nai.
输入样例1
3
Itai nyan~
Ninjin wa iyadanyan~
uhhh nyan~
(结尾无空行)
输出样例1
nyan~
(结尾无空行)
输入样例2
3
Itai!
Ninjinnwaiyada T_T
T_T
(结尾无空行)
输出样例2
nai
(结尾无空行)
思路
- 采用gets()函数PAT测试显示编译错误,故编写input()函数输入字符串,遇到换行结束输入
- 本题需要找到最长相同的结尾字符串,为了解题方便,用自定义reverse()函数将字符串前后反转,依次进行遍历
- 输入的字符串数 2 ≤ N ≤ 100,先将输入的两个字符串最长相同的结尾字符串找到,存放在数组same中
- 逐个字符串输入将每个字符串反转后与same字符串进行比较,找到最长相同的字符长度
C语言代码
#include<stdio.h>
#include<string.h>
const int STR_LEN = 256; //字符串最大长度
//将字符串str反转
void reverse(char *str){
int len = strlen(str);
for(int i = 0; i < len/2; i++){
char temp = str[i];
str[i] = str[len-1-i];
str[len-1-i] = temp;
}
}
//输入函数,遇到'\n'结束输入
void input(char *str){
for(int i = 0; i < STR_LEN+1; i++){
scanf("%c", &str[i]);
if(str[i]=='\n'){
str[i] = '\0'; //字符串结尾需要用'\0'结束
return;
}
}
}
int main(){
int n, k_len;
char s1[STR_LEN+1], s2[STR_LEN+1],same[STR_LEN+1] = {0};
scanf("%d", &n);
getchar(); //吸收输入数字n之后的换行符
input(s1);
input(s2);
reverse(s1);
reverse(s2);
//得到字符串s1、s2反转后最长相同的字符串same
for(int i = 0; i < strlen(s1) && i < strlen(s2); i++){
if(s1[i] == s2[i]){
same[i] = s1[i];
k_len = i+1; //记录same字符串的长度
}
else
break;
}
n = n - 2;
while(n--){ //循环输入剩下的n-2个字符串
int i;
char s3[STR_LEN+1];
input(s3);
reverse(s3);
//将same字符串与反转后的s3字符串遍历比较,找到最长相同的字符串,更新same
for(i = 0; i < k_len && i < strlen(s3) ; i++){
if(same[i] != s3[i]){
k_len = i;
same[k_len] = '\0'; //以'\0'结尾
break;
}
}
if(i == strlen(s3)) { //如果正常结束循环,则表示相同字符长度小于same,更新same
k_len = i;
same[k_len] = '\0';
}
}
if(k_len == 0)
printf("nai");
else{
reverse(same);
for(int i = 0; i < k_len; i++)
printf("%c", same[i]);
}
return 0;
}
注意:
- 字符串在处理时若使用<string.h>头文件中的函数,则必须保证字符串以’\0’结束,否则在调用reverse()时调用strlen()函数出现错误,出现数组越界等情况难以察觉错误原因
- 在找最长相同长度的字符串时,要考虑正常结束循环时的情况
采用枚举法
#include<stdio.h>
#include<string.h>
char s[100][256];
int n, minlen = 256, ans = 0;
void input(char *str){
for(int i = 0; i < 256+1; i++){
scanf("%c", &str[i]);
if(str[i]=='\n'){
str[i] = '\0';
return;
}
}
}
int main(){
int n;
scanf("%d", &n);
getchar();
//将输入的每个字符串存放在二维数组的每一行中
for(int i = 0; i < n; i++){
input(s[i]);
int len = strlen(s[i]);
if(len < minlen) minlen = len; //找到最短的字符串长度
for(int j = 0; j < len/2; j++){ //反转字符串
char temp = s[i][j];
s[i][j] = s[i][len-j-1];
s[i][len-1-j] = temp;
}
}
for(int i = 0; i < minlen; i++){ //将字符串逐个逐个字符进行比对
char c = s[0][i];
bool same = true;
for(int j = 1; j < n; j++){ //每一个字符串的第i个字符进行比较
if(c != s[j][i]){
same = false;
break;
}
}
if(same) ans++;
else break;
}
if(ans){
for(int i = ans-1; i >= 0; i--)
printf("%c",s[0][i]);
}else
printf("nai");
return 0;
}