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

来源:互联网 发布:mac ariana grande 编辑:程序博客网 时间:2024/05/18 00:08

这篇博客记录了《编程珠玑》第一章的对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);}}}elsecout << "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