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

使用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. Linux wget 安装JDK失败

    windows 下安装的话,查看网络,就会发现,是带cookie,回调参数Authparam 验证的

  2. Unicode与UTF-8互转(C语言实现) 基本原理

    1. 基础 1.1 ASCII码 我们知道, 在计算机内部, 所有的信息最终都表示为一个二进制的字符串. 每一个二进制位(bit)有0和1两种状态, 因此八个二进制位就可以组合出 256种状态, 这被 ...

  3. linux 内核库函数 【转】

    转自:http://blog.chinaunix.net/uid-20321537-id-1966892.html 当编写驱动程序时,一般情况下不能使用C标准库的函数.Linux内核也提供了与标准库函 ...

  4. 原 android重启应用(应用重新启动自身)

    private void restartApplication() { final Intent intent = getPackageManager().getLaunchIntentForPack ...

  5. 【ACM】不要62 (数位DP)

    题目:http://acm.acmcoder.com/showproblem.php?pid=2089 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新 ...

  6. appium+python自动化24-滑动方法封装(swipe)【转载】

    swipe介绍 1.查看源码语法,起点和终点四个坐标参数,duration是滑动屏幕持续的时间,时间越短速度越快.默认为None可不填,一般设置500-1000毫秒比较合适. swipe(self, ...

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

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

  8. yum安装jdk环境变量配置

    系统版本 [root@localhost ~]# cat /etc/redhat-release CentOS Linux release (Core) #安装之前先查看一下有无系统自带jdk rpm ...

  9. python 将windows字体中的汉字生成图片的方法

    #encoding: utf-8import osimport pygame chinese_dir = '黑体常规'if not os.path.exists(chinese_dir): os.mk ...

  10. 牛客小白月赛3 I 排名【结构体排序/较复杂/细节】

    链接:https://www.nowcoder.com/acm/contest/87/I 来源:牛客网 题目描述 Cwbc和XHRlyb都参加了SDOI2018,他们特别关心自己的排名. 我们定义每一 ...