概述
题目
搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。
假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。),请你统计最热门的10个查询串,要求使用的内存不能超过1G。
思路
第一步:用Hashmap(STL中叫unordered_map)统计词频
第二步:用容量为K的最小堆取出出现次数最大的K个词
(参考 http://blog.csdn.net/fuyufjh/article/details/48369801)
代码
#include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <map>
#include <string>
#include <unordered_map>
using namespace std;
typedef pair<string, int> Record;
struct RecordComparer {
bool operator() (const Record &r1, const Record &r2) {
return r1.second > r2.second;
}
};
vector<Record> TopKNumbers(vector<string> &input, int k) {
unordered_map<string, int> stat;
for (const string &s : input) stat[s]++;
priority_queue<Record, vector<Record>, RecordComparer> heap;
auto iter = stat.begin();
for (int i = 0; i < k && iter != stat.end(); i++, iter++) {
heap.push(*iter);
}
for (; iter != stat.end(); iter++) {
if (iter->second > heap.top().second) {
heap.pop();
heap.push(*iter);
}
}
vector<Record> result;
while (!heap.empty()) {
result.push_back(heap.top());
heap.pop();
}
return result;
}
/******** 测试代码 *********/
int main() {
clock_t cbegin, cend;
vector<string> test;
char buf[20];
for (int i = 0; i < 100; i++) {
int x = rand() % 20;
sprintf(buf, "STR%d", x);
test.push_back(string(buf));
}
auto result = TopKNumbers(test, 5);
for (auto it = result.rbegin(); it != result.rend(); it++) {
cout << it->first << 't' << it->second << endl;
}
printf("============================n");
sort(test.begin(), test.end());
for (const string &s : test) {
cout << s << endl;
}
}
Ref
- http://blog.csdn.net/v_JULY_v/article/details/6403777
最后
以上就是虚拟钢铁侠为你收集整理的取出现次数最多的K个数题目思路代码Ref的全部内容,希望文章能够帮你解决取出现次数最多的K个数题目思路代码Ref所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复