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;
}