题意:
给定若干个字符串,将其分组,按照组成元素相同为一组,输出数量最多的前5组,每组按照字典序输出所。
有字符串。数量相同的输出字典序较小的一组。
注意:
每个输出时每个字符串只能出现一次。
解析:
可以先将所有的字符串利用字典树hash,并利用vector进行保存。
然后对vector进行标号,这样只要对标号进行排序,而不用对vector进行排序。效率大大提高。
my code
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#define pb push_back
using namespace std;
const int maxnode = 50005;
const int sigma_size = 26;
struct Trie {
int ch[maxnode][sigma_size];
int val[maxnode];
int sz, clock;
void clear() { clock = sz = 1; memset(ch[0], 0, sizeof(ch[0]));}
Trie() { clear(); }
int idx(char c) { return c - 'a'; }
int hash(const char *s) {
int u = 0, n = strlen(s);
for(int i = 0; i < n; i++) {
int c = idx(s[i]);
if(!ch[u][c]) {
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
if(!val[u]) val[u] = clock++;
return val[u];
}
} trie;
int idx[maxnode];
vector<string> ans[maxnode];
bool cmp(int lhs, int rhs) {
if(ans[lhs].size() != ans[rhs].size())
return ans[lhs].size() > ans[rhs].size();
if(ans[lhs].size() != 0)
return ans[lhs][0] < ans[rhs][0];
}
void init() {
trie.clear();
for(int i = 0; i < maxnode; i++)
ans[i].clear();
}
string str, save;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
init();
while(cin >> str) {
save = str;
sort(save.begin(), save.end());
int u = trie.hash(save.c_str());
ans[u].pb(str);
}
for(int i = 1; i < trie.clock; i++)
idx[i] = i;
sort(idx+1, idx+trie.clock, cmp);
for(int i = 1; i <= 5; i++) {
int id = idx[i], size = ans[id].size();
if(size == 0) break;
cout <<"Group of size " << size << ": ";
sort(ans[id].begin(), ans[id].end());
for(int j = 0; j < size; j++) {
if(j == 0 || ans[id][j] != ans[id][j-1])
cout << ans[id][j] << " ";
}
cout << "." << endl;
}
return 0;
}