百练:2408:Anagram Groups

1、解题思路

根据题意需要对一连串字符串进行分类,分类标准为最小字典序排列相同,则根据分类和输出标准可以构造一个结构体,结构体如下:

struct node{
    set<string> s_set;
    string new_string;
    string old_first_string;
    int num;
}s_node[30001];

1、其中s_set用于存储字符串,这里依照题目要求用了set的两个性质:1) 无重复元素 2)自动排序

2、其中num为这一类的总个数(注意总个数不一定等于最终这一类输出的个数,因为输出个数去除了相同元素)

3、new_string:为这一类的特征(按最小字典序排序后的字符串)

4、old_first_string:第一个存入set的字符串

除了构造结构体,为了方便查找字符串属于哪一个类,使用了map来将类特征(排序后的字符串)映射到类下标(数组下标)。

有了结构体后就可以对输入的每一个字符串进行排序,排完序使用map来查找s_node数组对应的类下标,若没有则开辟一个新类,有则更新。

2、源代码

#include <iostream>
#include <set>
#include <map>
#include <algorithm>
using namespace std;
struct node{
	set<string> s_set;
	string new_string;
	string old_first_string;
	int num;
}s_node[30001];
map<string, int> s_i;
bool cmp(node x, node y){
	if(x.num == y.num)
		return x.old_first_string < y.old_first_string;
	return x.num > y.num;
}
int main (){
	int Total = 0;
	string temp;
	while(cin>>temp){
		string y = temp;
		sort(temp.begin(), temp.end());
		if(s_i.find(temp) == s_i.end()){  // 无对应map则创建一个新node
			s_i[temp] = Total; 
			s_node[Total].num++;
			s_node[Total].new_string = temp;
			s_node[Total].old_first_string = y;
			s_node[Total].s_set.insert(y);
			Total++; 
		}else{  // 有对应map则存入对应的node的set中并且字符串数量+1 
			s_node[s_i[temp]].num++;
			s_node[s_i[temp]].s_set.insert(y);
		}
	}
	sort(s_node, s_node+Total, cmp);  // 按数量+字典序排序 
	for(int i = 0 ; i < 5; i++){  // 取前五个输出 
		if(s_node[i].num == 0)
			break;
		cout<<"Group of size "<<s_node[i].num<<": ";
		for(set<string>::iterator it = s_node[i].s_set.begin(); it != s_node[i].s_set.end(); ++it) {
			cout<<*it<<" ";		
		}
		cout<<"."<<endl;
	}
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章