PAT (Advanced Level) Practice 1077 Kuchiguse (20 分) 凌宸1642

题目描述:

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?

译:日语以句尾助词而有名。这种粒子的个人偏好可以看作是说话人个性的反映。这种偏好被称为“Kuchiguse”,在动画和漫画中经常被艺术地夸大。例如,人工造句结尾的助词“nyan~”经常被用作一种刻板印象,用来形容具有猫一样性格的人物:
Itai nyan~(好痛,nyan~)
Ninjin wa iyada nyan~(我讨厌胡萝卜,nyan~)
现在给出几个相同角色的台词,你能找到她的 Kuchiguse 吗?


Input Specification (输入说明):

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.

译:每个输入包含 1 个测试用例,对于每个测试用例,第一行是一个整数 N (2 ≤ N ≤ 100)。 接下来 N 行是 长度为 0 到 256 (包含) 个字符的字符串,每行代表一个角色的台词。语音是区分大小写的。


Output Specification (输出说明):

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.

译:对于每个测试用例,在一行中打印该字符的 kuchiguse,即所有 N 行中最长的公共后缀。如果没有这样的后缀,输出 nai


Sample Input 1 (样例输入 1 ):

3
Itai nyan~
Ninjin wa iyadanyan~
uhhh nyan~

Sample Output 1 (样例输出 1 ):

nyan~

Sample Input 2 (样例输入 2 ):

3
Itai!
Ninjinnwaiyada T_T
T_T

Sample Output 2 (样例输出 2 ):

nai

The Idea:

这题的思路很简单,就是 N 个字符串,从每个字符串末尾开始,一一比较,如果这个所有字符串中均有这个字符,则这个字符一定在最长公共后缀中;往前遍历,依次类推。知道 N 行中出现某行的字符出现不用为止。

由于确定循环遍历的最短次数,所以采用 vectorpair 结合,对vector 中的元素按照 key 从小到大排序(直觉感觉 map 会比较的时候不好操作,所以选择了 vector pair 的操作)。存的时候用字符串的长度作为 key ,字符串的逆序作为 value (因为比较是从后往前的) , 都与第一个字符的每个字符比较,如果所有字符串该位置下的字符都相同的时候,将其记录下来,当出现不同的字符之时,说明需要提前终止循环。

最后输出的答案就是我们记录下来的所有字符的 逆序

The Codes:

#include<bits/stdc++.h>
using namespace std ;
int n ;
string s , ans = "" ; // ans 总记录公共后缀
vector<pair<int , string> > in ; // vector 向量 ,其中的每一个元素都是 pair<int,string>容器
bool cmp(pair<int , string> a , pair<int , string> b){
	return a.first < b.first ; // vector向量的排序是按照pair元素的第一个元素的升序排列,即字符串长度
}
int main(){
	cin >> n ;
	getchar() ; // 吸收回车符 (用完 cin 后,如果要用 getline 一定要先吸收 回车符)
	for(int i = 0 ; i < n ; i ++){ 
		getline(cin , s) ; // 输入第 i 个字符串
		reverse(s.begin() , s.end()) ; // 将字符串进行 reverse 操作,倒置
		in.push_back(make_pair(s.size() , s)) ; // 往in中加入该字符串长度,与该字符串的逆的pair
	}
	sort(in.begin() , in.end() , cmp) ; // 将 vector 中所有 pair 元素按照 key 的升序排列
	for(int i = 0 ; i < in[0].first ; i ++){ // 最短的是第 0 个字符串,故循环次数最多就是它的长度
		char  temp = in[0].second[i] ; // 第 0 个字符串的 第 i 个字符作为本次比较的字符
		bool flag = true ; // 标志本次比较是否会出现不同的字符
		for(int j = 1 ; j < in.size() ; j ++){
			if(in[j].second[i] != temp){
				flag = false ; // 如果某个字符串的第 i 个字符与当前字符不相同,标志位 false 跳出循环
				break;
			}
		} 
		if(flag) ans += temp ; // 如果所有字符串的第 i 个字符都相同,那么把该字符加入到答案中
		else break ; // 出现不同的字符,循环可以提前结束
	}
	if(ans == "") cout<< "nai" <<endl ; // ans 为空串,则表明没有相同的后缀,按题目要求输出 nai
	else{
		reverse(ans.begin() , ans.end()) ; // 将答案倒置(倒着比较,存的是倒序,需要倒回来)
		cout<< ans << endl ; // 输出答案
	}
	return 0;
}