【海量数据处理】N个数中找出最大的前K个数
2016-05-02 22:36
375 查看
N个数中找出最大的前K个数,需要用小堆实现。
分析:由于小堆的堆顶存放堆中最小的数据,可以通过与堆顶数据进行比较,将大数据存放在堆中,注意在每次改变堆顶数据后,进行调堆,使堆顶一直存放整个堆中最小元素。
春节期间,A公司的支付软件某宝和T公司某信红包大乱战。春节后高峰以后,公司Leader要求后台的攻城狮对后台的海量数据进行分析。先要求分析出各地区发红包金额最多的前100用户。现在知道人数最多的s地区大约有1000w用户。
分析:由于小堆的堆顶存放堆中最小的数据,可以通过与堆顶数据进行比较,将大数据存放在堆中,注意在每次改变堆顶数据后,进行调堆,使堆顶一直存放整个堆中最小元素。
void AdjustDown(int *a, size_t root, size_t size)//下调 {//小堆 size_t parent = root; size_t child = parent * 2 + 1; while (child < size) { if (child + 1 < size && a[child] > a[child + 1]) { ++child; } if (a[parent] > a[child]) { swap(a[parent], a[child]); parent = child; child = parent * 2 + 1; } else//注意不满足交换条件时跳出本次循环 { break; } } void CreateRetPacket(vector<int>& moneys)//创建N个数 { srand((unsigned int)time(NULL)); //srand(time(0)); moneys.reserve(N); for (size_t i = 0; i<N; i++) { moneys.push_back(rand() % 1000);//产生N个随机值 } for (size_t i = K; i < N; ++i) { moneys[i] *= 100; } } void GetTopk(const vector<int>& moneys, int n, int k)//N个数中找最大的前k个数--小堆实现 { assert(n>k); int *TopkArray = new int[k];//通过前k个元素建立含有k个元素的堆 for (size_t i = 0; i < k; i++) { TopkArray[i] = moneys[i]; } for (int i = (k - 2) / 2; i >= 0; --i)//建小堆 { AdjustDown(TopkArray, i, k); } //从第k个元素开始到第n个元素分别与堆顶元素进行比较,较大数据入堆顶,再对整个堆进行下调,使堆顶存放最小元素(小堆) for (size_t i = k; i < n; ++i) { if (moneys[i] > TopkArray[0]) { TopkArray[0] = moneys[i]; AdjustDown(TopkArray, 0, k); } } size_t count = 0; for (size_t i = 0; i < k; ++i)//打印k个最大数据,即堆中所有元素 { cout << TopkArray[i] << " "; ++count; if (count % 10 == 0) { cout << endl; } } cout << endl; delete[] TopkArray;//注意释放TopkArray所占的内存 TopkArray = NULL; }测试用例如下:
#include<iostream> #include<assert.h> #include<vector>//容器--类模板 #include<stdlib.h>//利用随机值 #include<time.h> using namespace std; #define N 10000 #define K 100 void Test8() {//N个里面找最大的前k个数 vector<int> moneys; CreateRetPacket(moneys); GetTopk(moneys, N, K); }上述可实现下列题:
春节期间,A公司的支付软件某宝和T公司某信红包大乱战。春节后高峰以后,公司Leader要求后台的攻城狮对后台的海量数据进行分析。先要求分析出各地区发红包金额最多的前100用户。现在知道人数最多的s地区大约有1000w用户。
相关文章推荐
- 网卡安装常见问题精解
- css网页布局中注意的几个问题小结
- 使用mysql中遇到的几个问题
- 装完linux以后需要注意的问题
- .net中前台javascript与后台c#函数相互调用问题
- 一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out
- SQLite字符串比较时的大小写问题解决方法
- PHP动态规划解决0-1背包问题实例分析
- jquery1.8版本使用ajax实现微信调用出现的问题分析及解决办法
- 搭建SSH时的思考和遇到的几个问题的解决方法
- 我认为JSP有问题(下)
- php猴子选大王问题解决方法
- JSP应用的安全问题
- 令PHP初学者头疼十四条问题大总结
- 大数据量,海量数据处理方法总结
- 数据库相关问题
- php 面试碰到过的问题 在此做下记录
- php 大数据量及海量数据处理算法总结
- 浅析栈区和堆区内存分配的区别
- mysql 海量数据的存储和访问解决方案