当前位置: 首页 > news >正文

文件中海量数据的排序

文件中海量数据的排序

题目:

跟之前堆排序可以解决TopK问题一样,我们来看看归并排序会用来解决什么问题?

image-20240520225512621

思路:

我们说归并排序是外排序。其实就是将数据分成一个个小段,在内存中进行排序,再拿出内存,在外部,比如文件(磁盘中),进行归并排序。

其实就是数据量太大,无法直接通过内存来排序,我们将其平均切割成100份,1000份等等,比如将其切割成原数据切割成100份,每份拿出来就可以放到内存中去排序,排完之后放到一个个小文件中。

这样就会有100个小文件,这100个小文件里面都是排序好的数据,然后让文件去归并,让上一个文件和下一个文件中的数据去归并,最终实现的就是全部数据都放在一个文件里,并且是有序的。

文件的合并思路如下图所示

image-20240520233956417

文件归并的过程就是在文件中进行的,就是在磁盘上进行的。这就是外排序

image-20240521111447944

具体的归并思路:

就是让两个文件归并后的文件跟下一个文件接着归并。

image-20240521114326528

让file1 指向mfile文件,file2指向下一个文件,继续归并file1 和 file2文件,生成mfile文件

image-20240521114307224

然后就一直循环,直至mfile文件和第 n 个文件归并后。就结束。

代码实现:

void MergeFile(const char* file1, const char* file2, const char* mfile)
{// 打开file1 文件FILE* fout1 = fopen(file1, "r");if (fout1 == NULL){perror("MergeFile():fopen:fout1");exit(-1);}// 打开file2文件FILE* fout2 = fopen(file2, "r");if (fout2 == NULL){perror("MergeFile():fopen:fout2");exit(-1);}// 打开mfile文件,准备写入。FILE* fin = fopen(mfile, "w");if (fin == NULL){perror("MergeFile():fopen:fin");exit(-1);}// 将file1 和 file2的数据读出来,归并到mfile文件中int num1, num2;int ret1 = fscanf(fout1, "%d\n", &num1);int ret2 = fscanf(fout2, "%d\n", &num2);while (ret1 != EOF && ret2 != EOF) // 通过fscanf的返回值来判断是否有文件读取完毕{// 判断num1 和 num2 谁大谁小if (num1 < num2){fprintf(fin, "%d\n", num1); // 小的数据放到fin指向的文件ret1 = fscanf(fout1, "%d\n", &num1);// 这一步是为了让文件指针++ 读取下一个数据}else{fprintf(fin, "%d\n", num2);ret2 = fscanf(fout2, "%d\n", &num2);}}// 走到这里,有可能是fout1 或者是 fout2 文件先读取完// 要把剩下的进行处理while (ret1 != EOF){fprintf(fin, "%d\n", num1);ret1 = fscanf(fout1, "%d\n", &num1);}while (ret2 != EOF){fprintf(fin, "%d\n", num2);ret2 = fscanf(fout2, "%d\n", &num2);}// 关闭文件fclose(fout1);fclose(fout2);fclose(fin);
}void MergeSortFile(const char* file)
{// 读取传进来的file文件FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen:fout");exit(-1);}// 读取文件中的数据 ,将其分割成多组,在内存中进行排序,再放入对应文件中int n = 10; // 将文件中的数据切割成10个一组int num = 0;int* a = (int*)malloc(sizeof(int) * n); // 用于在内存中进行排序的数组int i = 0;int filei = 1; // 每组数据所存放的文件的下标char subfile[20]; // 用于存放各组数据文件的文件while (fscanf(fout, "%d\n", &num) != EOF) // 从文件中读取数据,写到num中 [读取失败返回EOF]{// 将读出来的数据放到一个数组中if (i < n - 1) // 只读前n - 1个到数组中 第n个在else中处理{a[i++] = num;}else{// 走进循环,fscanf还是读了一个数据到num上,要记得处理a[i] = num;// 走到这里,说明已经把文件中的数据全部读取到数组a中// 对其进行快排QuickSort(a, 0, n - 1);// n - 1是最后一个元素的下标// 排序完之后,我们将数据放回到文件中,这里我们选择每一组数据都放进一个文件中sprintf(subfile, "sub\\sub_sort%d.txt", filei++); // 创建各个文件的名字FILE* fin = fopen(subfile, "w"); // 打开subfile所记载的文件名,如果没有,由于是w形式 会自动创建一个if (fin == NULL){perror("fopen:fin");exit(-1);}// 往文件里写,我们排好序的数组for (int j = 0; j < n; j++){fprintf(fin, "%d\n", a[j]);}fclose(fin);i = 0; // 重置i}}// 现在文件中的数据, 被我们分成了一组组个数为n的有序数据,并放在了对应的文件中// 我们对这个文件,进行归并排序。  也就是在磁盘上进行文件内数据的归并,是外排序char mfile[100] = "12";char file1[100] = "sub\\sub_sort1.txt";char file2[100];char subsortfile[100] = "subsortfile\\12";  // 将归并后的mfile子文件都放到subsortfile文件中for (int i = 2; i <= n; i++){sprintf(file2, "sub\\sub_sort%d.txt", i);// 读取file1 和 file2的数据  归并到subsortfile文件的mfile子文件中MergeFile(file1, file2, subsortfile);// 更新file1指向的文件名strcpy(file1, subsortfile);// 更新mfilesprintf(mfile, "%s%d", mfile, i + 1);// 更新subsortfile的mfile子文件名sprintf(subsortfile, "subsortfile\\%s", mfile);}fclose(fout);
}

测试效果如下:

Sort是原数据存放的地方,我们这里只放了小数据,便于我们调试。

image-20240521134218393

sub文件中:

image-20240521134237892

subsortfile文件中:

image-20240521134311397

最终的12345678910就是所有文件归并后的结果。

将一开始的Sort文件内的数据,有序的存放在1234568910这个文件中

image-20240524121012351

相关文章:

文件中海量数据的排序

文件中海量数据的排序 题目&#xff1a; 跟之前堆排序可以解决TopK问题一样&#xff0c;我们来看看归并排序会用来解决什么问题&#xff1f; 思路&#xff1a; 我们说归并排序是外排序。其实就是将数据分成一个个小段&#xff0c;在内存中进行排序&#xff0c;再拿出内存&am…...

java项目之视频网站系统源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的视频网站系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 视频网站系统的主要使用者管…...

262 基于matlab的一级倒立摆仿真

基于matlab的一级倒立摆仿真&#xff0c;在对一级倒立摆进行数学建模的基础上&#xff0c;对模型进行线性化&#xff0c;得到其状态空间模型&#xff0c;利用二次型最优控制方法得出控制率。输出角度和位置优化曲线。程序已调通&#xff0c;可直接运行。 262 一级倒立摆仿真 状…...

智能无网远控再升级 向日葵Q2Pro升级版发布

无网或者内网设备也想要进行远程控制&#xff0c;是不是听上去有些天方夜谭了&#xff1f;其实这类特种设备的远程控制需求是非常强的&#xff0c;比如医疗/工控设备的远程运维、使用指导教学等等。 实际上&#xff0c;只要这类设备有屏幕&#xff0c;支持可视化的桌面操作&am…...

2024电工杯A题详细思路代码分析数学建模:园区微电网风光储协调优化配置

题目分析&#xff1a;园区微电网风光储协调优化配置 我们会先给出三个问题总体的分析&#xff0c;最后会详细分析问题一的建模和详细内容。 背景&#xff1a; 园区微电网由风光发电和主电网联合为负荷供电&#xff0c;为了尽量提高风光电量的负荷占比&#xff0c;需配置较高比…...

Docker搭建mysql性能测试环境

OpenEuler使用Docker搭建mysql性能测试环境 一、安装Docker二、docker安装mysql三、测试mysql连接 一、安装Docker 建立源文件vim /etc/yum.repos.d/docker-ce.repo增加内容[docker-ce-stable] nameDocker CE Stable - $basearch baseurlhttps://repo.huaweicloud.com/docker…...

关于开启直连v2rayn代理Fiddler Charles bp抓包失败问题

Fiddler 使用插件&#xff1a;proxy switchyomega 配置代理8888端口为fiddler && charles的监听端口 此时fiddler提示代理已更改点击变更捕获&#xff0c;这时不需要进行点击只需要开启上述插件即可抓到包并且国外代理&#xff0c;如果点击的话回自动更新为原来的ip 即…...

Python 爬虫编写入门

一、爬虫概述 网络爬虫&#xff08;Web Crawler&#xff09;或称为网络蜘蛛&#xff08;Web Spider&#xff09;&#xff0c;是一种按照一定规则&#xff0c;自动抓取互联网信息的程序或者脚本。它们可以自动化地浏览网络中的信息&#xff0c;通过解析网页内容&#xff0c;提取…...

Linux网络编程(socket)

1. 概念 局域网和广域网 局域网&#xff1a;局域网将一定区域内的各种计算机、外部设备和数据库连接起来形成计算机通信的私有网络。广域网&#xff1a;又称广域网、外网、公网。是连接不同地区局域网或城域网计算机通信的远程公共网络。 IP&#xff08;Internet Protocol&a…...

以太坊(3)——智能合约

智能合约 首先明确一下几个说法&#xff08;说法不严谨&#xff0c;为了介绍清晰才说的&#xff09;&#xff1a; 全节点矿工 节点账户 智能合约是基于Solidity语言编写的 学习Solidity语言可以到WFT学院官网&#xff08;Hello from WTF Academy | WTF Academy&#xff09;…...

【Python设计模式03】简单工厂模式

简单工厂模式&#xff08;Simple Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它通过专门定义一个工厂类来负责创建其他类的实例&#xff0c;而不是在客户端代码中直接实例化对象。这样可以将对象创建的过程与使用对象的过程分离&#xff0c;提高代码的可维护…...

java中的Collections类+可变参数

一、概述 Collections类是集合类的工具类&#xff0c;与数组的工具类Arrays类似 二、可变参数(变&#xff1a;数量) 格式&#xff1a;参数类型名...参数&#xff0c;可变参数就是一个数组 注意&#xff1a;可变参数必须放在参数列表的最后并且一个参数列表只能有一个可变参…...

SpringBoot集成腾讯云敏感词校验API流程

1.pom.xml中引入腾讯云jar配置信息 <dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java</artifactId><version>4.0.11</version> </dependency> 2.application.yaml中添加配置 tencent…...

android 避免混淆类名和方法名,但是方法内容需要被混淆

要避免在使用 ProGuard 或 R8 进行代码混淆时混淆特定类名和方法名的同时让方法内容被混淆&#xff0c;你需要在 ProGuard 配置文件中使用 -keepclassmembers 或 -keep 规则。这些规则允许你指定保留类名和方法名的同时允许方法内部代码被混淆以减小体积和提高安全性。 以下是…...

通过ELRepo修改CentOS 7内核版本的详细步骤

简介&#xff1a; 在Linux系统中&#xff0c;内核版本决定了硬件支持和系统性能。有时&#xff0c;为了获得更好的性能或新特性&#xff0c;我们需要升级或更换内核。本文将详细说明如何在CentOS 7系统上通过ELRepo仓库安装更新的内核版本。 环境准备&#xff1a; CentOS 7系…...

C++开源库glog使用封装--自定义日志输出格式,设置日志保留时间

glog下载和编译 glog开源地址 https://github.com/google/glog glog静态库编译 cd /home/wangz/3rdParty/hldglog/glogmkdir out mkdir build && cd buildcmake .. -DCMAKE_INSTALL_PREFIX../out -DCMAKE_BUILD_TYPERelease -DBUILD_SHARED_LIBSOFF本文选择的glo…...

linux rc.local不生效

1. 权限问题直接 chmod 755 /etc/rc.d/rc.local 即可 2.本次发现问题 环境复杂造成&#xff0c;系统中有多个版本的JDK&#xff0c;导致tomcat无法启动 systemctl status rc-local.service ● rc-local.service - /etc/rc.d/rc.local CompatibilityLoaded: loaded (/usr/lib…...

ROS2入门21讲__第07讲__节点:机器人的工作细胞

目录 前言 通信模型 案例一&#xff1a;Hello World节点&#xff08;面向过程&#xff09; 运行效果 代码解析 创建节点流程 案例二&#xff1a;Hello World节点&#xff08;面向对象&#xff09; 运行效果 代码解析 创建节点流程 案例三&#xff1a;物体识别节点 …...

k8s node NotReady后会发生什么?

K8s 是一种强大的容器编排和管理平台&#xff0c;能够高效地调度、管理和监控容器化应用程序&#xff1b;其本身使用声明式语义管理着集群内所有资源模型、应用程序、存储、网络等多种资源&#xff0c;Node 本身又属于 K8s 计算资源&#xff0c;上面承载运行着各种类型的应用程…...

uni-starter创建App项目最全流程(日后还有其他功能会不断更新)

一、创建项目 在HbuilderX中点击创建项目&#xff0c;选择uni-starter模板&#xff0c;选择阿里云、Vue3&#xff0c;填写项目名称后点击创建。如果没有下载过uni-starter会自动下载该插件&#xff0c;如下图&#xff1a; 二、 创建云服务器并关联项目 如果是第一次使用&#…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...