TopK问题与如何在有限内存找出前几最大(小)项(纯c语言版)

news2024/11/16 17:51:29

目录

0.前言

1.知识准备

2.实现

1.首先是必要的HeapSort

2.造数据

其他注意事项

 3.TopK的实现


0.前言

在我们的日常生活中总有排名系统,找出前第k个分数最高的人,而现在让我们用堆来在有限内存中进行实现

1.知识准备

想要实现topk问题首先我们要有堆排序的知识 如果想要了解的可以看我这一篇堆的实现与堆排序(纯C语言版)-CSDN博客

2.实现

首先我们很容易想到,方法1就是建一个N个数的大堆,然后Pop k次这样我们就得到了前k个大的数,但是这样有个缺陷,当数据量过大时,我们将会浪费大量的内存,如要读取10亿个整数的话,需要大约4G的内存

那我们可以在1KB的情况下完成这个吗,答案是可以的

我们可以先建立一个只有K个数的小堆,然后后面读取的数据与堆顶数据比较,满足要求则覆盖掉堆顶数据再向下调整,只需要这样我们就只用不到kb实现了大数据的topk问题

接下来让我们看代码的实现

1.首先是必要的HeapSort

void HeapSort(elementType* arr,int size)
{
	//O(Nlogn)
	//for (int i = 0; i < size; i++)
	//{
	//	AdjustUp(arr, i);
	//}
	//O(n)
	for (int i = (size - 1 - 1)/2; i >= 0; i--)
	{
		AdjustDown(arr, i, size);
	}
	//进行排序 排序实质进行交换
	int end = size - 1;
	while (end>0)
	{
		Swap(&arr[0], &arr[end]);
		AdjustDown(arr, 0, end);
		end--;
	}

}
void AdjustDown(elementType* arr, int parent, int size)
{
	int child=parent*2+1;
	while (child< size)
	{
		//先比较左右孩子的大小 小堆举例
		if (child + 1 < size && arr[child] > arr[child + 1])//
			child++;
		if (arr[parent] > arr[child])
		{
			Swap(&arr[parent], &arr[child]);
			parent = child;
			child = child * 2 + 1;
		}
		else
		{
			break;
		}
	}

}

2.造数据

void CreateNDate()
{
	// 造数据
	int n = 10000;
	srand(time(0));
	const char* file = "data.txt";
	FILE* fin = fopen(file, "w");
	if (fin == NULL)
	{
		perror("fopen error");
		return;
	}

	for (size_t i = 0; i < n; ++i)
	{
		int x = rand() % 1000000;
		fprintf(fin, "%d\n", x);//1.注意在后面加上换行符向2.向文件中打印每个1000000以内的随机数
	}

	fclose(fin);
}

其他注意事项

当我们检测我们的程序是否正确的时候或者当我们发现我们程序出现了错误的时候,我们可以减少数据量,控制数据范围,手动添加特殊数据,就以我们的上面这个举例,当我们光看我们是否选择正确是相当困难的但是可以进行数据范围的控制可以

将int x = rand() % 1000000;

改为int x = rand() % 100;

这样数据范围就变为了0~99然后我们再去手动在我们生成的数据中添加特殊数据,这样我们就很容易就知道我们的程序是否正确

 3.TopK的实现

时间复杂度为O(\log k*(N-K))即深度(调整次数)乘以个数

void test03()//Topk解决方法2 只用k个整形数组的数据
{
	FILE* file = fopen("data.txt", "r");
	//先读取10个数据来进行堆的建立
	int k = 0;
	printf("请输入你要查找的前几大数据");
	scanf("%d", &k);
	int* arr = (int*)malloc(sizeof(int) * k);
	for (int i = 0; i < 10; i++)
	{
		fscanf(file, "%d", arr+i);
	}
	//先建立一个能够存储10个数据的堆
	for (int i = (k-1-1)/2; i>=0; i--)
	{
		AdjustDown(arr, i, k);
	}
	//然后开始读取后n-k个
	int x = 0;
	while (~fscanf(file,"%d",&x))
	{
		if (x > arr[0])
		{
			arr[0] = x;
			AdjustDown(arr, 0, k);
		}
	}
	printf("前k个最大数为->");
	HeapSort(arr, k);
	for (int i = 0; i < k; i++)
	{
		printf("%d ", arr[i]);
	}
	fclose(file);
	free(arr);

}

学习笔记fscanf中第一个参数要写要读的文件名,第二个要写读取的格式,第三个是接受的元素然后啊fscanf的返回值与为什么要加上~这个取反符号,fscanf是有返回值的当读取成功返回0,当读取失败返回-1取反为0
其他注意事项,记得关闭文件与释放内存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1883218.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【stm32】大一上学期笔记复制

砌墙单片机 外设是什么&#xff1f; ipage 8 nx轴 128 X0-127 y0-63 PWM脉冲宽度调制 PWM脉冲宽度调制 2023年10月13日 基本特性&#xff1a;脉冲宽度调制PWM是一种对模拟信号进行数字编码的方法。广泛引用于电机控制&#xff0c;灯光的亮度调节&#xff0c;功率控制等领域…

科普文:一文搞懂jvm原理(二)类加载器

概叙 科普文&#xff1a;一文搞懂jvm(一)jvm概叙-CSDN博客 前面我们介绍了jvm&#xff0c;jvm主要包括两个子系统和两个组件&#xff1a; Class loader(类装载器) 子系统&#xff0c;Execution engine(执行引擎) 子系统&#xff1b;Runtime data area (运行时数据区域)组件&am…

类和对象【上】【C++】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;LiUEEEEE                        …

试用笔记之-收钱吧安卓版演示源代码,收钱吧手机版感受

首先下载&#xff1a; https://download.csdn.net/download/tjsoft/89499105 安卓手机安装 如果有收钱吧帐号输入收钱吧帐号和密码。 如果没有收钱吧帐号点我的注册 登录收钱吧帐号后就可以把手机当成收钱吧POS机用了&#xff0c;还可以扫客服的付款码哦 源代码技术交流QQ:42…

Nuxt3 的生命周期和钩子函数(七)

title: Nuxt3 的生命周期和钩子函数&#xff08;七&#xff09; date: 2024/6/30 updated: 2024/6/30 author: cmdragon excerpt: 摘要&#xff1a;文章阐述了Nuxt3中Nitro生命周期钩子的使用&#xff0c;如nitro:config自定义配置、nitro:init注册构建钩子、nitro:build:be…

Python自动化,实现自动登录并爬取商品数据,实现数据可视化

关于如何使用Python自动化登录天 猫并爬取商品数据的指南&#xff0c;我们需要明确这是一个涉及多个步骤的复杂过程&#xff0c;且需要考虑到天猫的反爬虫策略。以下是一个简化的步骤指南&#xff1a; 步骤一&#xff1a;准备工作 环境准备&#xff1a;确保你的Python环境已经…

数据沿袭是止痛药还是维生素?

首先&#xff0c;这在很大程度上取决于用户组织当前的使用案例及其成熟度。 在我看来&#xff0c;数据工程师喜欢查看数据流并对依赖关系有直观的了解&#xff0c;但他们最终真的会使用数据沿袭吗&#xff1f;使用频率是多少&#xff1f;具体用例是什么&#xff1f; 从我们的观…

<电力行业> - 《第12课:配电(2)》

5 配网的指标 配电网与广大用户紧密联系&#xff0c;所以配电网是否合格还是十分重要的。 评判配电网的标准&#xff0c;主要有四个指标&#xff1a; 供电可靠性&#xff1a;供电可靠性是指针对用户连续供电的可靠程度。网损率&#xff1a;网损率可定义为电力网的电能损耗量与…

问题-小技巧-专业版Win11怎么启动电脑的休眠模式?

专业版Win11怎么启动电脑的休眠模式&#xff1f; powercfg -a powercfg -hibernate on 启用管理员面板依次输入上述命令就可以了。

短视频电商源码怎么选择

随着移动互联网的迅猛发展&#xff0c;短视频电商成为了一种热门的商业模式。很多商家和创业者都希望能够快速搭建一个短视频电商平台来推广和销售自己的产品。然而&#xff0c;选择合适的短视频电商源码并不是一件容易的事情。在选择之前&#xff0c;有一些关键因素需要考虑。…

控制器方法执行流程和 @InitBinder【Spring源码学习】

控制器方法执行流程 InitBinder 加在ControllerAdvice中 首先说明ControllerAdvice和aop没有任何关系&#xff01; 加在ControllerAdvice中只对所有控制器都生效 全局的在开始时就会保存到handlerMappingAdapter中的cache中&#xff1b; 加在Controller中 加在controller中只对…

小程序使用echarts和echarts配置项总结(全网最简单详细)

文章目录 概要小程序中使用echarts1. ec-canvas2. 下载项目3. 去echarts官网定制&#xff1a;4.点击下载5.引入使用 echarts的option配置知识点归纳整理&#xff08;还在更新&#xff09;&#xff1a;小结 概要 小程序中使用echarts&#xff08;简单详细&#xff09; 小程序中…

redis,memcached,nginx网络组件

课程目标&#xff1a; 1.网络模块要处理哪些事情 2.reactor是怎么处理这些事情的 3.reactor怎么封装 4.网络模块与业务逻辑的关系 5.怎么优化reactor? io函数 函数调用 都有两个作用&#xff1a;io检测 是否就绪 io操作 1. int clientfd accept(listenfd, &addr, &l…

[论文精读]Variational Graph Auto-Encoders

论文网址&#xff1a;[1611.07308] Variational Graph Auto-Encoders (arxiv.org) 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎…

已解决 SyntaxError: invalid syntax,Python报错原因和解决方案。

「作者简介」&#xff1a;冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础著作 《网络安全自学教程》&#xff0c;适合基础薄弱的同学系统化的学习网络安全&#xff0c;用最短的时间掌握最核心的技术。 这篇文章带大家…

【WSL2+Ubuntu+Docker Desktop】迁移到D盘

如果不会安装Ubuntu&#xff0c;可以看这篇文章 安装到C盘后先创建Ubuntu实例 下载完之后先创建实例&#xff0c;输入自己的实例名以及密码 迁移wsl-2 wsl默认保存在C:\Users<主机名>\AppData\Local下 随着在子系统上安装的软件/服务越来越多&#xff0c;C盘的空间也所…

前端——在本地搭建Vue单页应用

目录 1、安装最新node.js 2、打开命令行窗口 3、进入要保存项目的目录下 4、安装 Vue CLI 5、创建新项目&#xff0c;选择功能 5.1 新建项目 5.2 Please pick a preset 5.3 Check the features needed for your project 5.4 Choose a version of Vue.js 5.5 Use hist…

php 通过vendor文件 生成还原最新的composer.json

起因&#xff1a;因为历史原因&#xff0c;在本项目中composer.json基本算废了&#xff0c;没法直接使用composer管理扩展&#xff0c;今天尝试修复一下composer.json。 历史文件&#xff0c;可以看出来已经很久没有维护了&#xff0c;我们主要是恢复require的信息 {"na…

Linux4(Docker)

目录 一、Docker介绍 二、Docker结构 三、Docker安装 四、Docker 镜像 五、Docker 容器 六、Docker 安装nginx 七、Docker 中的MySQL部署 一、Docker介绍 Docker&#xff1a;是给予Go语言实现的开源项目。 Docker的主要目标是“Build,Ship and Run Any App,Anywhere” 也…

ROS2用c++开发参数节点通信

1.创建节点 cd chapt4/chapt4_ws/ ros2 pkg create example_parameters_rclcpp --build-type ament_cmake --dependencies rclcpp --destination-directory src --node-name parameters_basic --maintainer-name "joe" --maintainer-email "1027038527qq.com&…