思路很简单,先分段排序,存储到临时文件中,然后合并.

使用10000个整数来模拟大数据,每次读取100个到内存中.

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h> enum
{
enmMaxFileNameLen = ,
}; void SaveArrToFile(int32_t arrInt[], int32_t arrSize, const char *fileName);
void ReadArrFromFile(int32_t arrInt[], int32_t &arrSize, const int32_t amxArrSize, const char *fileName);
void ReadArrFromFilePtr(int32_t arrInt[], int32_t &arrSize, const int32_t amxArrSize, FILE *fp);
void RandomGenArrInt(int32_t arrInt[], int32_t arrSize);
void RandomGenData(int32_t numberCount);
void QSort(int32_t arrInt[], int32_t start, int32_t end);
void BigDataSort(const char *fileName, const int32_t maxNumberInMem);
int32_t Segment(const char *fileName, const int32_t maxNumberInMem);
int32_t MergeTwoFile(const char *fileName1, const char *fileName2, const char *fileOut);
void PrintArrInt(int32_t arr[], int32_t arrSize); int32_t main()
{
RandomGenData();
BigDataSort("data_10000.txt", );
getchar();
return ;
} void RandomGenArrInt(int32_t arrInt[], int32_t arrSize)
{
for (int32_t i = ; i < arrSize; ++i)
{
arrInt[i] = i + ;
}
for (int32_t i = ; i <= arrSize; ++i)
{
int32_t m = rand() % arrSize;
int32_t n = rand() % arrSize;
int32_t tmp = arrInt[m];
arrInt[m] = arrInt[n];
arrInt[n] = tmp;
}
} void SaveArrToFile(int32_t arrInt[], int32_t arrSize, const char *fileName)
{
FILE *fp = NULL;
fopen_s(&fp, fileName, "w");
if (!fp)
{
printf("open %s failed!\n", fileName);
return;
}
for (int32_t i = ; i < arrSize; ++i)
{
fprintf_s(fp, "%d,", arrInt[i]);
}
fclose(fp);
printf("save %s \n", fileName);
} void RandomGenData(int32_t numberCount)
{
int32_t *arr = new int32_t[numberCount];
RandomGenArrInt(arr, numberCount);
char fileName[enmMaxFileNameLen] = { };
sprintf_s(fileName, enmMaxFileNameLen,"data_%d.txt", numberCount);
SaveArrToFile(arr, numberCount, fileName);
} void QSort(int32_t arrInt[], int32_t start, int32_t end)
{
if (start >= end){ return; }
int32_t i = start, j = end;
int32_t tmp = arrInt[i];
while (i < j)
{
while (i < j && tmp < arrInt[j])
{
--j;
}
arrInt[i] = arrInt[j];
while (i < j && tmp >= arrInt[i])
{
++i;
}
arrInt[j] = arrInt[i];
}
arrInt[i] = tmp;
QSort(arrInt, start, i - );
QSort(arrInt, i + , end);
} void ReadArrFromFile(int32_t arrInt[], int32_t &arrSize, const int32_t amxArrSize, const char *fileName)
{
arrSize = ;
FILE *fp = NULL;
fopen_s(&fp, fileName, "r");
if (!fp)
{
printf("open %s failed!\n", fileName);
return;
}
while (arrSize < amxArrSize && !feof(fp))
{
fscanf_s(fp, "%d,", &arrInt[arrSize++]);
}
} void ReadArrFromFilePtr(int32_t arrInt[], int32_t &arrSize, const int32_t amxArrSize, FILE *fp)
{
arrSize = ;
while (arrSize < amxArrSize && !feof(fp))
{
fscanf_s(fp, "%d,", &arrInt[arrSize]);
if (!feof(fp))
{
++arrSize;
}
}
} void BigDataSort(const char *fileName, const int32_t maxNumberInMem)
{
int32_t segFileCount = Segment(fileName, maxNumberInMem);
int32_t fileIndex = ;
char fileName1[enmMaxFileNameLen] = { };
char fileName2[enmMaxFileNameLen] = { };
char fileOut[enmMaxFileNameLen] = { };
while (true)
{
sprintf_s(fileName1, "%d.txt", fileIndex++);
sprintf_s(fileName2, "%d.txt", fileIndex++);
sprintf_s(fileOut, "%d.txt", segFileCount++);
int32_t ret = MergeTwoFile(fileName1, fileName2, fileOut);
if (ret != )
{
break;
}
}
} int32_t Segment(const char *fileName, const int32_t maxNumberInMem)
{
int32_t *arr = new int32_t[maxNumberInMem];
FILE *fp = NULL;
fopen_s(&fp, fileName, "r");
if (!fp)
{
printf("open %s failed!\n", fileName);
return ;
}
int32_t tmpFileIndex = ;
while (true)
{
int32_t arrSize = ;
ReadArrFromFilePtr(arr, arrSize, maxNumberInMem, fp);
if (arrSize == )
{
break;
}
QSort(arr, , arrSize - );
char tmpFileName[enmMaxFileNameLen] = { };
sprintf_s(tmpFileName, enmMaxFileNameLen, "%d.txt", tmpFileIndex++);
SaveArrToFile(arr, arrSize, tmpFileName);
}
fclose(fp);
delete[] arr;
return tmpFileIndex;
} int32_t MergeTwoFile(const char *fileName1, const char *fileName2, const char *fileOut)
{
int32_t ret = ;
FILE *fp1 = NULL, *fp2 = NULL, *fpOut = NULL;
fopen_s(&fp1, fileName1, "r");
fopen_s(&fp2, fileName2, "r");
fopen_s(&fpOut, fileOut, "w");
if (!fileOut)
{
printf("open %s failed!\n", fileOut);
return ret;
}
int32_t val1 = , val2 = ;
if (fp1){ fscanf_s(fp1, "%d,", &val1); }
if (fp2){ fscanf_s(fp2, "%d,", &val2); }
while (fp1 && fp2 && !feof(fp1) && !feof(fp2))
{
if (val1 < val2)
{
// printf("%d ", val1);
fprintf_s(fpOut, "%d,", val1);
fscanf_s(fp1, "%d,", &val1);
}
else
{
// printf("%d ", val2);
fprintf_s(fpOut, "%d,", val2);
fscanf_s(fp2, "%d,", &val2);
}
ret = ;
}
while (fp1 && !feof(fp1))
{
// printf("%d ", val1);
fprintf_s(fpOut, "%d,", val1);
fscanf_s(fp1, "%d,", &val1);
}
while (fp2 && !feof(fp2))
{
// printf("%d ", val2);
fprintf_s(fpOut, "%d,", val2);
fscanf_s(fp2, "%d,", &val2);
}
if (fp1){ fclose(fp1); }
if (fp2){ fclose(fp2); }
fclose(fpOut);
printf("save %s \n", fileOut);
return ret;
} void PrintArrInt(int32_t arr[], int32_t arrSize)
{
for (int32_t i = ; i < arrSize; ++i)
{
printf("%d ", arr[i]);
}
}

C++ 大规模数据排序(100G数据 使用 4G 内存 排序)的更多相关文章

  1. 多线程更新已排序的Datagridview数据,造成数据错位

    多线程更新已排序的Datagridview数据,触发Datagridview的auto-sort时间,数据重新排序,造成后面更新数据的更新错误. 解决方法: 方法一.设置Datagridview的表头 ...

  2. ASP.NET中Dataset的table数据合并、数据截取、数据排序

    1.两个相同字段表的合并: public static DataSet CombineTables(DataSet _ds, DataTable _dt1, DataTable _dt2) { Dat ...

  3. for循环中进行联网请求数据、for循环中进行异步数据操作,数据排序错乱问题解决;

    for循环中进行联网请求数据,由于网络请求是异步的,第一个网络请求还没有回调,第二次第三次以及后续的网络请求又已经发出去了,有可能后续的网络请求会先回调:这时我们接收到的数据的排序就会错乱:怎么才能让 ...

  4. java中的排序(自定义数据排序)--使用Collections的sort方法

    排序:将一组数据按相应的规则 排列 顺序 1.规则:       基本数据类型:日常的大小排序. 引用类型: 内置引用类型(String,Integer..),内部已经指定规则,直接使用即可.---- ...

  5. Sortable拖拽排序插件数据筛选

    后台有拖拽排序功能,然而前段在开发的时候,一整页的数据都发给后端了. 于是查看前端代码,想到了如下解决办法,即先把排序前的保存,然后对比排序后的,有差异的才发回给后端. var new_ids_ord ...

  6. mysql必知必会(四、检索数据,五、排序检索数据,六、过滤数据,七、数据过滤)

    四.select语句 1.检索单个列 select prod_name from products; 2.检索多个列 select prod_name, prod_price from product ...

  7. 2.排序检索数据 ---SQL

    order by 一.排序数据 SELECT prod_name FROM Products ORDER BY prod_name; ORDER BY子句的位置 在指定一条ORDER BY子句时,应该 ...

  8. Spark SQL - 对大规模的结构化数据进行批处理和流式处理

    Spark SQL - 对大规模的结构化数据进行批处理和流式处理 大体翻译自:https://jaceklaskowski.gitbooks.io/mastering-apache-spark/con ...

  9. MySql——创建数据表,查询数据,排序查询数据

    参考资料:<Mysql必知必会> 创建数据表 在学习前首先创建数据表和插入数据.如何安装mysql可以看看上个博客https://www.cnblogs.com/lbhym/p/11675 ...

随机推荐

  1. 转:ExecutorService

    在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动.调度.管理线程的一大堆API了.在Java5以后,通过 Executor来启动线程比用Thread的start()更好.在新特征 ...

  2. GPS经纬度的表示方法及换算

    想要认识GPS中的经纬度,就必须先了解GPS,知道经纬度的来源: 1. GPS系统组成 GPS是 Gloabal Positioning System 的简称,意为全球定位系统,主要由地面的控制站.天 ...

  3. cygwin设置

    解决乱码问题 # 设置为中文环境,使提示成为中文  export LANG =" zh_CN.UTF-8 " # 输出为中文编码  export OUTPUT_CHARSET =& ...

  4. Java定义bean实体类中的变量时变量名的问题

    首先:TMD,这个问题花了我两个多小时,居然是因为一个字母的大小写导致的,我瞬间就&Y^%^&%&()*%¥%¥¥&^#@%&; 事情是酱紫的: 我定义了一个变 ...

  5. Fiddler抓包7-post请求(json)【转载】

    本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/tag/fiddler/ 前言上一篇讲过get请求的参数都在url里,post的请求相对于get ...

  6. HDU 6300.Triangle Partition-三角形-水题 (2018 Multi-University Training Contest 1 1003)

    6300.Triangle Partition 这个题就是输出组成三角形的点的下标. 因为任意三点不共线,所以任意三点就可以组成三角形,直接排个序然后输出就可以了. 讲道理,没看懂官方题解说的啥... ...

  7. kotlin扩展函数

    kotlin 扩展函数 https://www.kotlincn.net/docs/reference/extensions.html 扩展函数在android中的应用 fun AppCompatAc ...

  8. Count Numbers with Unique Digits -- LeetCode

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10^n. Exam ...

  9. POJ 3057 Evacuation(二分图匹配+BFS)

    [题目链接] http://poj.org/problem?id=3057 [题目大意] 给出一个迷宫,D表示门,.表示人,X表示不可通行, 每个门每时间单位只允许一个人通过, 每个人移动一格的为一时 ...

  10. POJ 2109 Inner Vertices(扫描线+树状数组)

    [题目链接] http://poj.org/problem?id=3109 [题目大意] 在一个棋盘上放满白子,现在把一些白子变成黑子, 如果一个白子上下左右都有黑子,就会变成黑子,问最终黑子个数 [ ...