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

使用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. git的回退和撤销操作

    回退是git的使用中很常用的一个操作,如果清楚各个回退命令的作用,不仅大大加快代码回退的效率,还能避免代码回退造成的事故 1.git reset --hard [commit] 清空暂存和未暂存的更改 ...

  2. Angular中checkbox实现复选

    需求:实现点击子选项,父选项自动勾选,当子选项没有勾选,对应的父选项不勾选,并把勾选的对应的id发送出去. 效果图: <!DOCTYPE html> <html data-ng-ap ...

  3. A simple greedy problem(hdu 4976)

    题意:有n个小兵,每个小兵有a[i]血量,第一个人每次只能对一个小兵砍一滴血,第二个人每次对所有生存的小兵砍一滴血. 最后看第一个人最多可以砍杀几个小兵. /* 首先,如果所有小兵的血量都不同的话,我 ...

  4. Linux下的GitHub安装与简单配置教程 ~ 转载

    Linux下的GitHub安装与简单配置教程   1.GitHub简介 Git是一个分布式版本控制系统,与其相对的是CVS.SVN等集中式的版本控制系统. 2.Git的安装 1)安装Git a.查看与 ...

  5. 生活大爆炸版锤子剪刀布(NOIP2014)(真·模拟)

    水!水!!水!!!(重要的事情说三遍..) 1分钟代码题.. 原题传送门 这题啊,手打BOOL判断,然后乱搞啊.. 这有什么难的.. 加个快读就能拿第一啦.. 膜9018上各位大佬们.. 下面贴代码 ...

  6. QT5.3.1 Quick 开发 --- 项目类型的选择(转)

    原文转自 https://www.cnblogs.com/aoldman/p/3966025.html 作为一个转行QT开发的新手,面对基于QML的开发时候 看到很多的项目类型感到很困惑,不知道应该怎 ...

  7. VS MFC RADIO控件 选择

    我们假设有两个RADIO控件:IDC_RADIO_SINGLE和IDC_RADIO_RANGE,我们的目的是默认选种IDC_RADIO_SINGLE控件. 方法一: CheckRadioButton( ...

  8. 10.OpenStack块存储服务

    添加块存储服务 安装和配置控制器节点 创建数据库 mysql -uroot -ptoyo123 CREATE DATABASE cinder; GRANT ALL PRIVILEGES ON cind ...

  9. flask的orm框架(SQLAlchemy)-操作数据

    # 原创,转载请留言联系 Flask-SQLAlchemy 实现增加数据 用 sqlalchemy 添加数据时,一定要注意,不仅仅要连接到数据表,并且你的创建表的类也必须写进来.而且字段和约束条件要吻 ...

  10. poj 3348(凸包面积)

    Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8063   Accepted: 3651 Description ...