编程珠玑笔记~排序10^7个数

题目要求:
对小于10000000的n个存在文件中的整数排序,要求:每个整数最多出现一次,
1MB可用内存,时间至多几分钟,运行时间10s左右最好。
Solution:
*方法一、1MB/4B=262144个整数,若要用文件排序大约40个通道,读文件40次,我们知道
*相对于内存操作,读磁盘的操作是相当慢的。
*方法二、用字符串存储每一个整数(一个数7个字节),对字符串排序,但是还是要读大于
*40次的磁盘。
*方法三、用第i个数表示i,整型数组,每一个占4B,1MB/4B=262144个数,不足表示1千万
*个数,char数组1MB/1B=1048576个数,不足表示1千万个数,1MB*8=8Mb=8388606,用位表示
*大约表示800万个数,依然不够,但是我们注意到对1000万个数最多分两次排序即可。
*第一个排序0~5000000的数,第二次排序5000000~10000000。

/**
 *Author: xiaoran
 *Time: 2016/01/05 21:25
 ******************
 *problem:对小于10000000的n个存在文件中的整数排序,要求:每个整数最多出现一次,
 *1MB可用内存,时间至多几分钟,10s左右最好
 *Solution:
 *方法一、1MB/4B=262144个整数,若要用文件排序大约40个通道,读文件40次,我们知道
 *相对于内存操作,读磁盘的操作是相当慢的。
 *方法二、用字符串存储每一个整数(一个数7个字节),对字符串排序,但是还是要读大于
 *40次的磁盘。
 *方法三、用第i个数表示i,整型数组,每一个占4B,1MB/4B=262144个数,不足表示1千万
 *个数,char数组1MB/1B=1048576个数,不足表示1千万个数,1MB*8=8Mb=8388606,用位表示
 *大约表示800万个数,依然不够,但是我们注意到对1000万个数最多分两次排序即可。
 *第一个排序0~5000000的数,第二次排序5000000~10000000。
 */
#include<cstdio>
#include<iostream>
#include<fstream>
#include<bitset>
#include<ctime>
using namespace std;
const int MAX=5000000;
int main()
{
    time_t t1=clock();
    //freopen("outputran.txt","r",stdin);
    //freopen("outputran1.txt","w",stdout);
    FILE *fp_in = fopen("outputran.txt", "r");
    FILE *fp_out = fopen("sort.txt", "w");
    bitset<MAX> bit;
    int a;
    while(fscanf(fp_in,"%d",&a)!=EOF){
        if(a<=MAX) bit.set(a, 1);
    }
    for(int i=0;i<=MAX;i++){
        if(bit[i]) fprintf(fp_out,"%d ",i);
    }
    fseek(fp_out, 0, SEEK_SET);
    bit.reset();
    while(fscanf(fp_in,"%d",&a)!=EOF){
        if(a>MAX){
            bit.set(a-MAX, 1);
        }
    }
    for(int i=0;i<=MAX;i++){
        if(bit[i]) fprintf(fp_out,"%d ",i+MAX);
    }
    time_t t2=clock();
    printf("\n%d ",(t2-t1)%1000000);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值