在存有10亿个数的文件中找到最大的100万个数
来源:互联网 发布:php编程教程 编辑:程序博客网 时间:2024/04/30 07:33
这是《编程珠玑》中的一道题目。10亿个整数,假设每个整数需要四个字节,如果使用排序的话,需要大约4G的内存,现在的很多pc都没有多这么内存,更不用说作者那个年代。
我们借助最小堆来解决这个问题。
主要步骤:
一、使用一个大小为一百万零一的整数数组来构建堆(堆的下标从1开始)
二、从文件中读取前一百万个数,每读入一个数,调用函数,保持其最小堆的性质,堆的根永远是堆中最小的元素。
三、从一百万零一个数开始,每读入一个数开始,比较这个数与堆的根比较,如果比根大,就用这个数替换掉根,调用函数,保持最小堆性质。
先生成10亿个随机数,使用的也是《编程珠玑》上的方法,将这10亿个数输出到data.txt中。
#include <stdlib.h>#include <stdio.h>int main(int argc, char *argv[]) {unsigned m, n;printf ("生成m个小于等于n的随机数!,请输入m和n:\n");scanf("%d%d", &m, &n);FILE *fp = fopen("data.txt", "w");/* 生成m个小于等于n的随机数 */unsigned i;for(i = 0; i < n; ++ i){int temp = rand();if((temp % (n - i)) < m){fprintf(fp, "%d\n", i);-- m;}}fclose(fp);return 0;}
生成了10亿个小于20亿的随机数,并且这10亿个数是不重复的。整个data.txt文件大约有10G,我的系统无法打开,内存不够。
然后就是从这10亿个数中选出前100万个最大的数。
#include <stdio.h>#include <stdlib.h>/* 定义堆的大小 */#define HEAPSIZE 1000000/* 使用数组来构建最小堆 */unsigned num[HEAPSIZE+1];/* 在堆的末尾插入新元素后,保持最小堆性质 */void siftup(int size){int i = size;unsigned parent, temp;while(1){if(i == 1)break;parent = i / 2;/* 已经是最小堆,退出 */if(num[parent] <= num[i])break;/* 交换父亲和儿子 */temp = num[parent];num[parent] = num[i];num[i] = temp;i = parent;}}/* 替换根元素后保持最小堆性质 */void siftdown(int size){int i = 1;unsigned child;while(1){child = 2 * i;if(child > size)break;/* child 是 i 的左儿子 */if(child + 1 <= size){/* 选取两个儿子中比较小的那个 */if(num[child+1] < num[child]){++child;}}/* 已经是最小堆,退出 */if(num[i] <= num[child])break;/* 交换父亲和儿子 */unsigned temp;temp = num[i];num[i] = num[child];num[child] = temp;i = child;}}int main(int argc, char *argv[]) {FILE *fp = fopen("data.txt", "r");unsigned i, number;unsigned count = 0;while(fscanf(fp, "%d", &number) != EOF){/* 前100万个数构建最小堆 */if(count < HEAPSIZE){++count;num[count] = number;siftup(count);continue;}/* 从100万零1个数开始,将当前数与根元素比较 */if(number > num[1]){num[1] = number;siftdown(count);}}fclose(fp);/* 将结果输出到文件中保存 */FILE *result_fp = fopen("result.txt", "w");for(i = 1; i <= HEAPSIZE; ++i){fprintf(result_fp, "%d\n", num[i]);}fclose(result_fp);return 0;}
前100万个数使用siftup函数构建最小堆,而后的数与堆的根比较,如果比根大,则替换掉根,并使用siftdown函数保持最小堆性质。
(如有疏漏之处,欢迎指正!)
- 在存有10亿个数的文件中找到最大的100万个数
- 在存有10亿个数的文件中找出100万个数
- 100万个数中找到最大的100个数
- 100万个数中找出最大的前100个数
- 算法实现:如何从100亿个数中找到最大的10000个数
- 从一亿个数中找出最大的一万个数或最小的一万个数
- 堆的应用——在N个数中找到最大的前K个数
- 如何从100万个数中找出最大的前100个数
- 如何从100万个数中找出最大的前100个数
- 从一亿个数中找出最大的一万个数
- 从一亿个数中找出最大的一万个数
- 从一亿个数中找出最大的一万个数【转】
- 谈从10亿个数中找出前10万个最大的
- 在m个数中寻找最大的n个数
- 【Quora】如何在2000个数中快速地找到最大的3个呢?
- 找到n个数中的最大的k个数
- 10个数取1万个最大的
- n个数里找出前m个数(或者 从10亿个浮点数中找出最大的1万个)
- Spring AOP 定义切入点
- 树形控件(Tree)的使用
- Linux /bin, /sbin, /usr/bin, /usr/sbin 区别
- mysql命令语法2
- MyEclipse10在win7下字体显示问题
- 在存有10亿个数的文件中找到最大的100万个数
- HDU 4655 Cut Pieces
- C3P0异常处理
- 图片浏览
- ACE在CentOS下的编译
- python2.7使用suds库调用webservice
- 加载大图片,内存溢出问题
- iOS 隐藏键盘
- Mean Shift算法(CamShift)