[C/C++]用堆实现TopK算法
一:引入
思考一个问题: 怎么在100个数中找到前10个最大的数?
way1: 相信大多数人想到的方法是先把100个数放到数组中从大到小排序,再打印前10个数
way2: 前一文中我们讲了堆结构,那么就可以把这100个数建为大堆,再依次pop10次
这种方法虽然再这个问题下可行,但是如果是再1亿个数中找最大的十个数呢?
当数据多到内存都放不下时这种方法显然不可取
二:TopK问题
TopK问题就是说在N个数据中找到前k个最大或最小的数(前提是N远大于k)
解决方法:
我们以找到前k个最大的数为例
- 将数据前k个数建成一个小堆
- 从第k+1个元素开始遍历数据,如果比堆顶元素大的话就交换
- 交换完以后,将堆顶元素向下调整到合适位置
- 依次反复遍历所有元素即可
为什么要建立小堆而不建大堆呢?
因为如果建大堆,如果数据中最大的元素堵在堆顶,那剩下的k-1大的元素就进不了堆了,相反如果建立小堆,大的数据会往下沉,堆顶的元素是堆里面最小的元素,只要后面的数据比堆顶大就可以交换入堆,这样遍历完一遍数据后,最大的k个数就全部在堆里面了
模拟验证:
在文件中创建10万个随机数,找前10个最大的数
1.先创建随机数
由于rand创建的随机数只有三万多个,而我们需要10万个,这样就会有许多重复的数据,加i是为了让重复的数据减少,取模100000是为了将随机数控制在100000以内
void creatnum()
{srand(time(0));int n = 100000;FILE* fin = fopen("data.txt", "w");if (fin == NULL){perror("fopen");return;}for (int i = 0; i < n; i++){int x = (rand() + i) % 100000; //由于rand最多只能产生三万多个随机数,加i可以让重复的数字大幅减小fprintf(fin,"%d\n",x);}fclose(fin);
}
2.打印前5个最大的数据(TopK问题精髓) 重点重点!!
对于向上调整法和向下调整法,可以看[C/C++]数据结构 堆的详解
void printTopk(const char* file,int k)
{FILE* fout = fopen(file, "r");if (fout == NULL){perror("fopen");return;}//创建一个小堆(找最大数创小堆,找最小数创大堆)int* heap = (HeapDataType*)malloc(sizeof(HeapDataType) * k);if (heap == NULL){perror("malloc");return;}for (int i = 0; i < k; i++){fscanf(fout, "%d", &heap[i]);AdjustUp(heap, i);}//读数据,如果比堆头的数大就交换,再向下调整int x = 0;while (fscanf(fout, "%d", &x) != EOF){if (x > heap[0]){heap[0] = x;AdjustDown(heap, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", heap[i]);}printf("\n");free(heap);fclose(fout);
}
3.测试代码
int main()
{creatnum();//printTopk("data.txt", 5);return 0;
}
由于10万个数都是随机产生的,所以我们无法验证打印的数是不是正确的,但是我们直到这十万个数都是小于100000的,所以我们先调用创建随机数的函数,然后我们在打开文件,改五个大于100000的数,看打印结果是不是我们改的数即可.
ps:在修改完数据后,准备打印数据之前,一定要把创建随机数的函数注释掉,因为再次调用的话,我们是以'w'的方式打开文件的,如果文件存在的话数据会被清空重新产升随机数,这样我们改的数据就不存在了


相关文章:
[C/C++]用堆实现TopK算法
一:引入 思考一个问题: 怎么在100个数中找到前10个最大的数? way1: 相信大多数人想到的方法是先把100个数放到数组中从大到小排序,再打印前10个数 way2: 前一文中我们讲了堆结构,那么就可以把这100个数建为大堆,再依次pop10次 这种方法虽然再这个问题下可行,但是如果是再1亿…...
3D点云目标检测:VoxelNex解读(带源码/未完)
VoxelNext 通用vsVoxelNext一、3D稀疏卷积模块1.1、额外的两次下采样1.2、稀疏体素删减 二、高度压缩三、稀疏池化四、head五、waymo数据集训练六、训练自己的数据集bug修改 通用vsVoxelNext 一、3D稀疏卷积模块 1.1、额外的两次下采样 使用通用的3D sparse conv,…...
【Docker】从零开始:11.Harbor搭建企业镜像仓库
【Docker】从零开始:11.Harbor搭建企业镜像仓库 1. Harbor介绍2. 软硬件要求(1). 硬件要求(2). 软件要求 3.Harbor优势4.Harbor的误区5.Harbor的几种安装方式6.在线安装(1).安装composer(2).配置内核参数,开启路由转发(3).下载安装包并解压(4).创建并修改配置文件(5…...
使用conan包 - 工作流程
使用conan包 - 工作流程 主目录 conan Using packages1 Single configuration2 Multi configuration 本文是基于对conan官方文档Workflows的翻译而来, 更详细的信息可以去查阅conan官方文档。 This section shows how to setup your project and manage dependenci…...
【LeeCode】59.螺旋矩阵II
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。 示例: 输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 解: class Solution {public int[][] generateMatrix(int n) {int[][] ar…...
rsyslog学习
rsyslog是什么 RSYSLOG(Remote System Logging)是一个开源的日志处理工具,用于在 Linux 和 Unix 系统上收集、处理和转发日志。它是一个健壮且高性能的日志处理程序,可以替换 Syslogd 作为标准的系统日志程序。RSYSLOG 提供了许多…...
Navicat 技术指引 | GaussDB服务器对象的创建/设计(编辑)
Navicat Premium(16.2.8 Windows版或以上) 已支持对GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能,还提供强大的高阶功能(如模型、结构同步、协同合作、数据迁移等),这…...
有哪些可信的SSL证书颁发机构?
目前市面上所显示的SSL证书颁发机构可所谓不计其数,类型也是多样,就好比我们同样是买一件T恤,却有百家不同类型的店铺一个道理。根据CA里面看似很多,但能拿到99%浏览器及设备信任度的寥寥无几,下面小编整理出几家靠谱可…...
MidJourney笔记(4)-settings
前面已经大概介绍了MidJourney的基础知识,后面我主要是基于实操来分享自己的笔记。可能内容顺序会有点乱,请大家理解。 这次主要是想讲讲settings这个命令。我们只需在控制台输入/settings,然后回车,就可以执行这个命令。 (2023年11月26日版本界面) 可能有些朋友出来的界…...
前端开发学习 (三) 列表功能
一、列表功能 1、列表功能 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compa…...
win11渗透武器库,囊括所有渗透工具
开箱即用,最全的武器库,且都是2023年11月最新版,后续自己还可以再添加,下载地址:https://download.csdn.net/download/weixin_59679023/88565739 服务连接 信息收集工具 端口扫描 代理抓包 漏洞扫描 指纹识别 webshel…...
13-21-普通数组、矩阵
LeetCode 热题 100 文章目录 LeetCode 热题 100普通数组13. 中等-最大子数组和14. 中等-合并区间15. 中等-轮转数组16. 中等-除自身以外数组的乘积17. 困难-缺失的第一个正数 矩阵18. 中等-矩阵置零19. 中等-螺旋矩阵20. 中等-旋转图像21. 中等-搜索二维矩阵II 本文存储我刷题的…...
代码随想录算法训练营第四十六天【动态规划part08】 | 139.单词拆分、背包总结
139.单词拆分 题目链接: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 求解思路: 单词是物品,字符串s是背包,单词能否组成字符串s,就是问物品能不能把背包装满。 动规五部曲 确定dp数…...
go语言基础 break和contine区别
背景 break和continue是编程语言的标准语法,几乎在所有的语言都有类似的用法。 go语言及所有其他编程语言for循环或者其他循环 区别 for i : 0; i < 10; i {if i 5 {continue}fmt.Println(i)for j : 0; j < 3; j {fmt.Println(strconv.Itoa(j) "a&q…...
vue3父子组件通过$parent与ref通信
父组件 <template><div><h1>ref与$parents父子组件通信 {{ parentMoney }}</h1><button click"handler">点击我子组件的值会减20</button><hr><child ref"children"></child></div> </te…...
PHP中的常见的超全局变量
PHP是一种广泛使用的服务器端脚本语言,它被用于开发各种Web应用程序。在PHP中,有一些特殊的全局变量,被称为超全局变量。超全局变量在整个脚本中都是可用的,无需使用global关键字来访问它们。在本文中,我们将深入了解P…...
leetcode9.回文数
回文数 0.题目1.WJQ的思路2.实现过程2.0 原始值怎么一个个取出来?2.1 取出来的数如何存到新的数字后面?2.2完整的反转得到新数的过程 3.完整的代码4.可运行的代码5.算法还可以优化的部分 0.题目 给你一个整数 x ,如果 x 是一个回文整数&…...
springboot(ssm大学生二手电子产品交易平台 跳蚤市场系统Java(codeLW)
springboot(ssm大学生二手电子产品交易平台 跳蚤市场系统Java(code&LW) 开发语言:Java 框架:ssm/springboot vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.7(或…...
关于微信小程序中如何实现数据可视化-echarts动态渲染
移动端设备中,难免会涉及到数据的可视化展示、数据统计等等,本篇主要讲解原生微信小程序中嵌入echarts并进行动态渲染,实现数据可视化功能。 基础使用 首先在GitHub上下载echarts包 地址:https://github.com/ecomfe/echarts-for…...
在Windows WSL (Linux的Windows子系统)上运行的Ubuntu如何更改主机名
在Windows 安装的Ubuntu,如何修改主机名。有列了两种方法,提供给大家参照。 文章目录 方法一:hostname指令修改方法二:修改配置文件修改hostnanmewsl.conf 文件配置选项推荐阅读 方法一:hostname指令修改 hostname指…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
