1000万条有重复的字符串,找出重复数前10的字符串
输入的时候可以使用map来存储,然后将map里的数据转到vector里,把重复数num按从大到小来排序之后,vector输出前10个即可。
#include <iostream> #include <algorithm> #include <map> #include <string> #include <vector> using namespace std; map<string, int> mp; struct node { string s; int num; node(string s,int num):s(s),num(num){} }; vector<node> v; bool cmp(const node&a, const node&b) { return a.num > b.num; } int main() { int n, m, i; string s; cin >> n; for (i=0; i<n; i++) { cin >> s; if (mp.find(s) != mp.end()) { mp[s] ++; } else { mp.insert(make_pair(s, 1)); } } map<string,int>::iterator it; for (it=mp.begin(); it!=mp.end(); it++) { node x(it->first, it->second); v.push_back(x); } sort(v.begin(), v.end(), cmp); for (i=0; i<10; i++) { cout << v[i].s << endl; } return 0; }
上面的做法其实在vector排序中是挺低效的,因为我们只需要找出10条信息,却把所有信息都排序了一边。
为了避免这样的时间浪费,可以使用一个只有10个元素的小根堆,不断地维护堆顶元素,使用迭代器把map遍历一遍之后,得到的小根堆里的10个元素就是所求答案了。
#include <cstdio> #include <iostream> #include <algorithm> #include <map> #include <string> #include <queue> #include <functional> using namespace std; map<string, int> mp; struct node { string s; int num; node(string s=NULL,int num=0):s(s),num(num){} }; struct cmp{ bool operator () (const node& a, const node& b) const { return a.num > b.num; } }; priority_queue<node, vector<node>, cmp> pq; int main() { int n, m, i; string s; cin >> n; for (i=0; i<n; i++) { cin >> s; if (mp.find(s) != mp.end()) { mp[s] ++; } else { mp.insert(make_pair(s, 1)); } } map<string,int>::iterator it; for (it=mp.begin(), i=0; it!=mp.end(); it++, i++) { if (i < 10) { node x(it->first, it->second); pq.push(x); } else { node x(it->first, it->second); if (it->second > pq.top().num){ pq.pop(); pq.push(x); } } } while (!pq.empty()) { cout << pq.top().s << endl; pq.pop(); } return 0; }