上亿个数据保存在硬盘中,找出最大的N个。
2013-01-28 22:51
190 查看
(1)先选N个元素组成一个小根堆,然后遍历剩下的数据,如果第i个元素M大于小根堆的根结点,就删除这个根结点,并将元素M插入这个小根椎,最后,小根堆中的元素就是最大的N个元素。
(2)只要开辟一个稍微大一点的缓冲区存放大于某选定值的数据即可,当缓冲满时,刷新选定值为缓冲区的第n大值,即可(同时清理缓存区)。
(3)用O(M)的时间找出第N大元素,然后再遍历一边找出比这个数大的N个数即可,理论复杂度O(M),不过N较小的时候可能是1L的更有效率
解法(1)及时考虑数据不可能全部加入内存,也可以在内存中开辟一个缓冲区,每次读取磁盘中的K(K<M)个数据进入内存,然后在一个一个的与堆进行比较。当缓冲区空时,则再读入K个数据。总之减少IO读取次数也是一个高效的重要方面。
解法(2)如何选定值
解法(3)是一个方向,可以使用快速排序算法,选择递归搜索的方向,理论上可以达到O(M),但找第N大元素时,如何不需要把所有数据读入内存呢?
给出方法(1)的一个算法,使用set,有重复数据也可以用multiset,set使用的是红黑树,可以改善插入、删除的效率
转自:http://bbs.csdn.net/topics/340000263
(2)只要开辟一个稍微大一点的缓冲区存放大于某选定值的数据即可,当缓冲满时,刷新选定值为缓冲区的第n大值,即可(同时清理缓存区)。
(3)用O(M)的时间找出第N大元素,然后再遍历一边找出比这个数大的N个数即可,理论复杂度O(M),不过N较小的时候可能是1L的更有效率
解法(1)及时考虑数据不可能全部加入内存,也可以在内存中开辟一个缓冲区,每次读取磁盘中的K(K<M)个数据进入内存,然后在一个一个的与堆进行比较。当缓冲区空时,则再读入K个数据。总之减少IO读取次数也是一个高效的重要方面。
解法(2)如何选定值
解法(3)是一个方向,可以使用快速排序算法,选择递归搜索的方向,理论上可以达到O(M),但找第N大元素时,如何不需要把所有数据读入内存呢?
给出方法(1)的一个算法,使用set,有重复数据也可以用multiset,set使用的是红黑树,可以改善插入、删除的效率
int main(int argc, char* argv[]) { set<int> set_MAX_N; ifstream inFile("test.txt"); int nTemp; while(inFile >>nTemp) { set_MAX_N.insert(nTemp); if(set_MAX_N.size() > N) { set_MAX_N.erase(set_MAX_N.begin()); } } for(set<int>::iterator it = set_MAX_N.begin();it != set_MAX_N.end(); it ++) cout<< *it <<endl; while(1); return 0; }
转自:http://bbs.csdn.net/topics/340000263
相关文章推荐
- 可保存数据数千年:日本开发新技术让细菌代替硬盘
- 使用JAVA找出一组数据的最大值
- 数据持久化的本质 - 数据保存成文件,存储到程序的沙盒中 -在应用程序结束时,将内存中的数据以文件的形式搬到(保存到)硬盘中
- 找出一堆数据中最大或者最小的K个数
- 【数据结构】找出N个数据中最大的前k个数据(利用堆排序)
- 找出数据集合中的最小值和最大值的两种算法比较
- 从1t数据中找出最大的10个数
- 移动硬盘数据保存的不安全性
- mysql中使用sql找出每组当中最大的那条数据
- 数据结构作业保存3-5返回指定区间内的最大值
- tsql 从数据表中找出缺失的最大、最小ID值。
- 求区间最大值---找出下面“输入数据及格式”中所描述的输入数据文件中最大重叠区间的大小
- [12,127,85,66,27,34,15,344,156,344,29,47,....] 这是某设备测量到的工程数据。 因工程要求,需要找出最大的5个值。
- Mysql中剔除重复字段并按主键降序排序后找出主键值最大的数据
- 给出一组整数型的数据,找出最大值,数据的个数是任意的
- 在规模为n的数据元素集合中找出最大元
- 从大量的数据中找出若干个最大或者最小的数据
- [java]键盘录入数值到数组-根据数值获取角标-找出数据中最大数值-反转数组
- 找出N个数据中的最大的K个数据---堆排序
- 移动硬盘 Windows-延缓写入失败:无法为某文件保存所有数据,数据已经丢失