TopK问题(用堆解决)

news2024/11/27 12:50:49

在这里插入图片描述
我们继续来延续我们上面的TopK问题,TopK问题一般是在解决有很多数的情况下,我们的k是个和小的值,然后我们是要找到最小或者最大的K个数,这类问题我们也称之为TopK问题,面对这种的问题,如果数字不是很大的情况下,我们就可以写一个循环,然后直接插入堆,进行向上调整就可以解决问题,但是现在这个数很大,我们如果插入数据的话消耗特别大,所以这里就只创建出来k个大小的存储进行建堆,这里我们把数据可以存在我们的文件当中,便于我们进行观察。

首先我们这里给出的问题是在这么多的数据当中找出最大的K个数字,第一个会困扰我们的就是我们应该建立大堆还是小堆呢,答案是小堆

我们先来分析为什么

首先我们如果是建大堆的话,如果第一次进堆的就是最大的数,那我们这里就会面临的是后面所以的数都进不了堆,我们是不是要比这个堆大才能进堆,这就好比我们的下水管道被堵住了,什么都进不去一样,所以这里是建立小堆,那我们这里还需要就是malloc出来一个k个大小的空间,先进行建堆,因为我们上面讲过建堆可以用向下调整的方式进行建堆,所以这里我们先完成这个步骤。

代码就是下面的这个。

// 建一个k个数小堆
	int* minheap = (int*)malloc(sizeof(int) * k);
	if (minheap == NULL)
	{
		perror("malloc error");
		return;
	}

	// 读取前k个,建小堆
	for (int i = 0; i < k; i++)
	{
		fscanf(fout, "%d", &minheap[i]);
		AdjustUp(minheap, i);
	}

然后我们给出的规定就是如果比这个堆顶的数字是要大的,我们就直接进行覆盖,堆顶的数就直接变成这个大的数,然后我们向下调整,等所有的数字都进行比较之后,我们也可以取出我们的所有数字了。

	while (fscanf(fout, "%d", &x) != EOF)
	{
		if (x > minheap[0])
		{
			minheap[0] = x;
			AdjustDown(minheap, k, 0);
		}
	}

那因为我们是写在文件当中的,所有我们这里还有一个知识点就是文件操作

我们之前学过文件的读写,也知道要对一个文件进行读写是要先打开我们的文件,如果是写的方式就是会创建,而且没一次都会先清空(如果是有这个文件的话,没有就进行创建)

那打开之后,我们得用fscanffprintf这两个函数进行,那大家可以查看文档,其实就是和scanfprintf有不太一样的。

在这里插入图片描述

在这里插入图片描述
看这个大家可以回忆起来,要是忘记了可以看之前的文章进行回顾,文章名字就是文件操作

那我们后面就是对文章的读写,然后进行操作,完整代码。

#define _CRT_SECURE_NO_WARNINGS 



#include<stdio.h>
#include<time.h>


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

	for (int i = 0; i < n; ++i)
	{
		int x = (rand() + i) % 10000000;
		fprintf(fin, "%d\n", x);
	}

	fclose(fin);
}

void PrintTopK(const char* file, int k)
{
	FILE* fout = fopen(file, "r");
	if (fout == NULL)
	{
		perror("fopen error");
		return;
	}

	// 建一个k个数小堆
	int* minheap = (int*)malloc(sizeof(int) * k);
	if (minheap == NULL)
	{
		perror("malloc error");
		return;
	}

	// 读取前k个,建小堆
	for (int i = 0; i < k; i++)
	{
		fscanf(fout, "%d", &minheap[i]);
		AdjustUp(minheap, i);
	}

	int x = 0;
	while (fscanf(fout, "%d", &x) != EOF)
	{
		if (x > minheap[0])
		{
			minheap[0] = x;
			AdjustDown(minheap, k, 0);
		}
	}

	for (int i = 0; i < k; i++)
	{
		printf("%d ", minheap[i]);
	}
	printf("\n");

	free(minheap);
	fclose(fout);
}

int main()
{
	CreateNDate();
	PrintTopK("Data.txt", 5);

	return 0;
}

当然这里还是需要注意一些东西,比如我们怎么知道那几个数是最大的,我们这里产生的随机数就是和有意思了

在这里插入图片描述
保证这些数字都是0-9999999,这里加i也有作用,主要是取决于我们的srand函数产生一定的随机数之后就只会产生相同的随机数了,所有这里的好处就是后面产生的随机数是加上i,因为i也是一直变的,我们只要在产生的随机数里改掉几个比1000000大的数就可以知道我们的代码是不是正确的额,可以直接用数组下标的方式,当然也可以在打开的文件里改,反正都可以来看,还有就是我们的调试窗口。

那我们今天的内容就到此结束了,我们下次再见。

在这里插入图片描述

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

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

相关文章

java--子类中访问其他成员的特点

1.在子类方法中访问其他成员(成员变量、成员方法)&#xff0c;是依照就近原则的。 ①先子类局部范围找。 ②然后子类成员范围找。 ③然后父类成员范围找&#xff0c;如果父类范围还没有找到则报错。 2.如果父类中&#xff0c;出现了重名的成员&#xff0c;会优先使用子类的…

linux 磁盘管理、分区管理常用命令

文章目录 基础命令挂载新硬盘/分区添加内存交换分区swaplvm分区管理模式 基础命令 查看目录文件大小 du -sh /backup du -sh /backup/* du -sh *查看磁盘挂载信息 df -lhT查看某个目录挂载在哪个分区&#xff0c;以及分区的磁盘使用情况 df [目录] #例如&#xff1a;df /ho…

【Linux】cd 命令使用

cd&#xff08;英文全拼&#xff1a;change directory&#xff09;命令用于改变当前工作目录的命令&#xff0c;切换到指定的路径。 ~ 也表示为 home 目录 的意思。. 则是表示目前所在的目录。.. 则表示目前目录位置的上一层目录。 语法 cd [目录] 命令选项及作用 执行令 …

平均模式恒流控制的LED驱动器:FP7122,打造舒适照明环境的绝佳选择

目录 一、 FP7122概述 二、 FP7122特点 三、 FP7122应用 近年来&#xff0c;随着LED照明技术的迅猛发展&#xff0c;LED驱动器在家庭照明、商业照明以及植物灯等领域扮演着至关重要的角色。其中&#xff0c;平均模式恒流控制的LED驱动器已经成为人们追求舒适照明环境的首选。…

齐活!Spring工程整合Redis实战汇总

&#x1f388;个人公众号:&#x1f388; :✨✨✨ 可为编程✨ &#x1f35f;&#x1f35f; &#x1f511;个人信条:&#x1f511; 知足知不足 有为有不为 为与不为皆为可为&#x1f335; &#x1f349;本篇简介:&#x1f349;本篇记录Spring工程整合Redis实战汇总操作&#xff0…

经典神经网络——GoogLeNet模型论文详解及代码复现

论文地址&#xff1a;[1409.4842] Going Deeper with Convolutions (arxiv.org) 一、GoogLeNet概述 创新点 我认为&#xff0c;这篇文章最大的创新点是引入了一个名为Inception块的结构&#xff0c;能够增加神经网络模型大小的同时&#xff0c;减缓参数量的爆炸式增长&#x…

Java第二十章 ——多线程

本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 在这之前&#xff0c;首先让我们来了解下在操作系统中进程和线程的区别&#xff1a;   进程&#xff1a;每个进程都有独立的代码和数据空间&#xff08;进程上下文…

服务化通信OPC实操

实操也是基于视频进行一些笔记&#xff0c;没得写就少写了 准备 Nuget包准备&#xff1a;OPCfoundation 一般都是使用Ua&#xff0c;当然也是有&#xff1a; 客户端链接服务器参数&#xff1a;IP Port 认证 登录用户名 Session 的实例化创建 进行使用&#xff1a; 因为Ses…

NAS层协议学习(三)

消息结构 每个NAS消息包含一个协议鉴别符和一个消息标识。协议鉴别符是一个 4 位值&#xff0c;指示正在使用的协议&#xff0c;即对于 EPS NAS 消息是 EMM 或 ESM。消息标识指示发送的特定消息。 EMM 消息还包含一个安全标头&#xff0c;指示消息是否受到完整性保护和/或加密…

AI视觉识别有哪些工业应用

AI视觉识别&#xff0c;主要是利用人工智能算法对图像或视频数据进行分析和处理&#xff0c;以提取关键信息并执行筛选、判断、预警等任务。AI视觉识别涵盖多种应用&#xff0c;如人脸识别、目标检测和识别、图像分割、行为识别、视频分析等。本篇就简单介绍一下AI视觉识别的应…

Dockerfile讲解

Dockerfile 1. 构建过程解析2. Dockerfile常用保留字指令3. 案例3.1. 自定义镜像mycentosjava83.2. 虚悬镜像 4. Docker微服务实战 dockerfile是用来构建docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。 dockerfile定义了进程需要的一切东西&…

OpenAI神秘项目Q-star曝光,人类永生或灭绝,将在我们有生之年发生

上周&#xff0c;OpenAI人事风波暂停的尾声中&#xff0c;有个“可能威胁人类”的、代号为“Q*”的神秘项目被抛掷出来。 传言中&#xff0c;Sam Altman被解雇前&#xff0c;几名研究人员向董事会发了一封信&#xff0c;警告一项强大的人工智能发现可能威胁到人类&#xff0c;而…

网络渗透测试(认识)

ARP协议 逻辑地址变成物理地址 32bit的IP地址变换成48bit的mac地址 ARP两个字节&#xff08;0x0806&#xff09; ARP解析协议 每一个主机都有ARP高速缓存&#xff0c;此缓存中记录了最近一段时间的内其他IP地址与其MAC地址的对应关系 如果本机想与某台主机通信&#xff0c;首先…

某医生用 ChatGPT 在 4 个月内狂写 16 篇论文,其中 5 篇已发表,揭密ChatGPT进行论文润色与改写的秘籍

如果写过学术论文&#xff0c;想必会有这样的感受&#xff1a; 绞尽脑汁、茶饭不思、夜不能寐、废寝忘食、夜以继日&#xff0c;赶出一篇论文&#xff0c;然后还被导师点评&#xff0c;“写得就是一坨&#xff01;” 可是&#xff0c;却有人4个月产出了16篇论文&#xff0c;成功…

03、K-means聚类实现步骤与基于K-means聚类的图像压缩

03、K-means聚类实现步骤与基于K-means聚类的图像压缩&#xff08;1&#xff09; K-means聚类实现步骤 开始学习机器学习啦&#xff0c;已经把吴恩达的课全部刷完了&#xff0c;现在开始熟悉一下复现代码。对这个手写数字实部比较感兴趣&#xff0c;作为入门的素材非常合适。…

嵌入式八股 | 笔试面试 | 校招秋招 | 详细讲解

〇、前言 作者&#xff1a;赛博二哈 本嵌入式八股撰写初衷&#xff1a;当时求职翻遍了我能找到的所有八股&#xff0c;不论是嵌入式的&#xff0c;计算机基础的&#xff0c;C艹的&#xff0c;都很难看下去&#xff0c;细究其原因&#xff0c;有个最大的痛点&#xff1a; 大部…

OCR常用数据集_看数据集区分可识别语言

这里写目录标题 COCO-TEXT 英文Total-Text 英文少量中文IIIT5K[50]、IC03[44]、IC13[34]、IC15[33]、CT80[56]MJSynth 英文SynthText分层文本数据集 (HierText) 英文TextOCR和IntelOCR &#xff1f;&#xff1f;&#xff1f;Multi-language dataset (IC19)RCTW17 主要中文MSRA-…

开源语音大语言模型——Qwen-Audio

论文链接&#xff1a;https://arxiv.org/pdf/2311.07919.pdf 开源代码&#xff1a;https://github.com/QwenLM/Qwen-Audio 一、背景 大型语言模型&#xff08;LLMs&#xff09;由于其良好的知识保留能力、复杂的推理和解决问题能力&#xff0c;在通用人工智能&#xff08;AGI…

链表的反转—c++版本

一、迭代反转法 过程分析&#xff1a; 代码实现&#xff1a; #include <iostream>struct LinkNode{ //创建一个结构体做为链表的结点int data; //数据域LinkNode* next; //指针域 };void Print_Link(LinkNode* phead) //打印链表 {while (phead ! nu…

cadence virtuoso simulation文件夹删除

ADE XL仿真结果错误&#xff0c;与预期结果差别太大&#xff0c;与ADE L仿真结果也差别很大。 可能是由于仿真数据过多&#xff0c;卡爆了。 在virtuoso启动路径下&#xff0c;simulation文件夹是仿真过程文件&#xff0c;可以将此文件夹清空。 清空后ADE XL仿真结果正常了。…