[C++](编程珠玑)10^7个数据量的磁盘文件排序

这篇博客记录了《编程珠玑》第一章的对10^7数据量的磁盘文件排序。

一、问题描述:

输入:一个最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数)的文件,其中每个数都小于等于n,且

n=10^7。
输出:得到按从小到大升序排列的包含所有输入的整数的列表。
条件:最多有大约1MB的内存空间可用,但磁盘空间足够。且要求运行时间在5分钟以下,10秒为最佳结果。

二、分析问题

用位向量表示10 000 000个整数需要10 000 000个位,10000000 bits = 1.192MB.所以程序员可利用的1MB空间是显然不够的,

可以采用两趟算法,第一趟利用5000000个位来排序0~4999999之间的整数,然后在第二趟中排序排序5000000~9999999之间的整数。

即:k趟算法可以在kn的时间开销和n/k的空间开销内完成对最多n个小于n的无重复正整数的排序。

三、代码

#include<iostream>
#include<stdio.h>
#include<bitset>
#include<fstream>
using namespace std;
const int MAX=500;
bitset<MAX+1> bit;
int main() {
	int num,i;
	ifstream infile;
	infile.open("E:\\ZTE\\Number.txt");
	if (infile.is_open()) {
		while (infile.good() && !infile.eof()) {
			infile >> num;
			if (num <= MAX)
				bit.set(num, 1);
			else if (num > 2 * MAX) {
				cout << "输入数据超出范围" << endl;
				return 0;
			}
		}
		for (i = 0;i < MAX + 1;++i) {
			if (bit[i] == 1) {
				cout << i << endl;
				bit.reset(i);
			}
		}
		

	}
	else
		cout << "can't open the file" << endl;
	infile.close();
	infile.open("E:\\ZTE\\Number.txt");
	if (infile.is_open()) {
		while (infile.good() && !infile.eof()) {
			infile >> num;
			if (num > MAX)
				bit.set(num-MAX, 1);
			else if (num > 2 * MAX) {
				cout << "输入数据超出范围" << endl;
				return 0;
			}
		}
		for (i = 0;i < MAX+1;++i) {
			if (bit[i] == 1) {
				cout << i+MAX << endl;
				bit.reset(i);
			}
		}
	}
	infile.close();
	system("pause");
	return 0;
}
其中读取的txt文件,是随机产生的,其代码如下:

#include<iostream>
#include<time.h>
#include<fstream>
using namespace std;
const int N = 10000000;
int arr[N];
void _swap(int& a, int& b) {
	int t = a;
	a = b;
	b = t;
}
int _rand(int _min, int _max) {
	return (rand() % (_max - _min + 1)) + _min;
}

int main() {
	srand((unsigned int)time(NULL));
	ofstream outfile;
	outfile.open("E:\\ZTE\\Number.txt");
	int i;
	int k = N-1;
	for (i = 0;i < N;++i)
		arr[i] = i;
	for (i = 0;i < k;++i) {
		_swap(arr[i], arr[_rand(i + 1, N - 1)]);
	}	
	/*
	cout << "输出换序后的结果" << endl;
	for (i = 0;i < N;++i) {
		cout<<i<<": "<<arr[i]<<endl;
	}
	*/
	if (outfile.is_open())
	{	
		for (i = 0;i < N;++i) {
			outfile << arr[i] << endl; 
		}
		outfile.close();
	}
	else
	{
		cout << "不能打开文件!" << endl;
	}
	system("pause");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值