[数据结构——lesson10.2堆排序以及TopK障碍]
目录
前言
学习目标
堆排序
TopK问题:
解法一:建立N个数的堆
解法二:建立K个数的堆(最优解)
完整代码
结束语
前言
上节内容我们详细讲解了堆[数据结构——lesson10.堆及堆的调整算法],接下来我们来讲解堆的一个经典应用——TopK问题。
学习目标
- 堆排序
- 掌握堆的应用理解TopK问题
两种调整算法的复杂度精准剖析
开头讲了两种堆的调整算法,分别是【向上调整】和【向下调整】,在接口算法实现Push和Pop的时候又用到了它们,以及在建堆这一块我也对它们分别做了一个分析,所以我们本文的核心就是围绕这两个调整算法来的,但是它们两个到底谁更加优一些呢❓
这里就不做过多解释,直接看图即可
1、向下调整算法【重点掌握】
2、向上调整算法
好,我们来总结一下,【向上调整算法】,它的时间复杂度为O(NlogN);【向下调整算法】,它的时间复杂度为O(N)
很明显,【向下调整算法】来得更优一些,因为向下调整随着堆的层数增加结点数也会变多,可是结点越多调整得就越少,因为在一些大型数据处理场合我们会使用向下调整
当然在下面要讲的堆排序中我们建堆也是利用的向下调整算法,所以大家重点掌握一个就行
堆排序
讲了那么久的堆,学习了两种调整算法以及它们的时间复杂度分析,接下去我们来说说一种基于堆的排序算法——【堆排序】
堆排序即利用堆的思想来进行排序,总共分为两个步骤:1. 建堆
- 升序:建大堆
- 降序:建小堆
这里我们以升序为例(升序建大堆 or 小堆❓)
- 在上面解说的时候,我建立的默认都是大堆,但是在这里我们要考虑排序问题了,现在面临的是【升序】,对于升序就是数组前面的元素小,后面的元素大,这个堆也是基于数组建立的,那就是要堆顶小,堆顶大,很明显就是建【小堆】
- 一波分析猛如虎,我们通过画图来分析是否可以建【小堆】
- 可以看到,对于建小堆来说,原本的左孩子结点就会变成新的根结点,而右孩子结点就会变成新的左孩子结点,整个堆会乱,而且效率并不是很高,因此我们应该反一下,去建大堆
//建立大根堆(倒数第一个非叶子结点) for (int i = ((n - 1) - 1) / 2 ; i >= 0; --i) { Adjust_Down(a, n, i); }
所以应建大堆。
堆排序的基本思路是每次将堆顶元素取出放到有序区间。大堆(大顶堆)中每个节点的值都大于或等于其子节点的值,堆顶元素为最大值。升序排序时建大堆,可将堆顶的最大值与无序区间最后一个数交换,使有序区间增加一个最大值。然后对剩余元素重新调整堆结构,重复此过程,就能逐渐将序列变为升序。
若升序建小堆,虽然堆顶是最小值,但确定次小值时会很麻烦,因为次小值可能是堆顶的左孩子或右孩子,甚至需要重新建堆,导致排序效率降低。
如何进一步实现排序❓
- 有了一个大堆之后,如何去进一步实现升序呢,这里就要使用到在Pop堆顶数据的思路了,也就是现将堆顶数据与堆底末梢数据做一个交换,然后对这个堆顶数据进行一个向下调整,将大的数往上调。具体过程如下
2. 利用堆删除思想来进行排序建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。
- 对照代码,好好分析一下堆排的全过程吧
/*堆排序*/ void HeapSort(int* a, int n) { //建立大根堆(倒数第一个非叶子结点) for (int i = ((n - 1) - 1) / 2 ; i >= 0; --i) { Adjust_Down(a, n, i); } int end = n - 1; while (end > 0) { swap(&a[0], &a[end]); //首先交换堆顶结点和堆底末梢结点 Adjust_Down(a, end, 0); //一一向前调整 end--; } }
- 看一下时间复杂度,建堆这一块是O(N),调整这一块的话就是每次够把当前堆中最的数放到堆底来,然后每一个次大的数都需要向下调整O(log2N),数组中有N个数需要调整做排序,因而就是O(Nlog2N)。
- 当然你可以这么去看:第一次放最大的数,第二次是次大的数,这其实和我们上面讲过的向上调整差不多了,【结点越少,调整越少;结点越多,调整越多】,因此它也可以使用之前我们分析过的使用的【错位相减法】去进行求解,算出来也是一个O(Nlog2N)。
- 最后将两段代码整合一下,就是O(N + Nlog2N),取影响结果大的那一个就是O(Nlog2N),这也就是堆排序最终的时间复杂度
TopK问题:
Top-K 问题是一类常见的算法和数据处理问题,指从包含 N 个元素的大量数据集合中找到前 K 个最大或最小的元素,通常 N 远大于 K。
Top-k问题在生活中是非常的常见,比如游戏中某个大区某个英雄熟练度最高的前10个玩家的排名,我们就要根据每个玩家对该英雄的熟练度进行排序,可能有200万个玩家,但我只想选出前10个,要对所有人去排个序吗?显然没这个必要。
再比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。
- 问题特点:数据量 N 极大时,若直接对所有数据排序(如快排,时间复杂度为 O (n log n)),不仅耗时久,还可能需将所有数据加载到内存,空间成本极高。而 K 通常很小,只需关注 “最大或最小的前 K 个”,无需对所有数据排序,因此需要更高效的算法来解决。
解法一:建立N个数的堆
建一个 N 个数的堆(C++中可用优先级队列priority_queue),不断的选数,选出前 k 个。
时间复杂度:建N个数的堆为O(N),获取堆顶元素 (也即是最值) 并删除掉堆顶元素为O(log2N),上述操作重复 k 次,所以时间复杂度为O(N+k*log2N)。
【思考】
但是这样也会存在上述所讲的可能需将所有数据加载到内存,空间成本极高的问题,能否再优化一下呢?
解法二:建立K个数的堆(最优解)
解决思路(堆排序)
- 若要找前 K 个最大的元素,则建立小顶堆;
- 若要找前 K 个最小的元素,则建立大顶堆。
- 首先用数据集合中前 K 个元素来建堆,然后将剩余的 N-K 个元素依次与堆顶元素比较;
- 若大于(针对小顶堆)或小于(针对大顶堆)堆顶元素,则替换堆顶元素并重新调整堆;
- 遍历完剩余元素后,堆中的 K 个元素就是所求的前 K 个最大或最小的元素。
时间复杂度:
▶ 建 k 个元素的堆为O(K);
▶ 遍历剩余的 N-K 个元素的时间代价为O(N-K),假设运气很差,每次遍历都入堆调整;
▶ 入堆调整:删除堆顶元素和插入元素都为O(log2K);
▶ 所以时间复杂度为O(k + (N-K)log2K)。当 N 远大于 K 时,为O(N*log2K),这种解法更优。假如要找出最大的前 10 个数:
▶ 建立 10 个元素的小堆,数据集合中前 10 个元素依次放入小堆,此时的堆顶元素是堆中最小的元素,也是堆里面第 10 个最小的元素,
▶ 然后把数据集合中剩下的元素与堆顶比较,若大于堆顶则去掉堆顶,再将其插入,
▶ 这样一来,堆里面存放的就是数据集合中的前 10 个最大元素,
此时小堆的堆顶元素也就是堆中的第 10 个最大的元素思考:为什么找出最大的前10个数,不能建大堆呢?
- 找出最大的前 10 个数不能建大堆,原因在于大堆的特性会导致只能找到最大的数,而无法找到其余较大的数。
- 大堆的性质是堆顶元素为堆中最大的元素。当使用 10 个元素建大堆时,堆顶就是这 10 个元素中最大的,若数据集合中还有其他更大的数,由于它们都小于当前堆顶元素,根据大堆的插入规则,这些数无法进入堆中。所以最终只能得到最大的那个数,无法找出前 10 个最大的数。
- 相反,若建立小堆,堆顶是堆中最小的元素,当有比堆顶大的元素出现时,就可以替换堆顶元素,并通过调整堆结构使小堆性质得以维持,这样就能保证较大的数逐渐进入堆中,最终堆中的 10 个元素就是数据集合中前 10 个最大的数。
完整代码
以从1w个数里找出最大的前10个数为例:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
// 大堆调整
void max_heapify(int* arr, int i, int size)
{
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left arr[largest])
largest = left;
if (right arr[largest])
largest = right;
if (largest != i)
{
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
max_heapify(arr, largest, size);
}
}
// 构建大根堆
void build_max_heap(int* arr, int size)
{
for (int i = size / 2 - 1; i >= 0; i--)
max_heapify(arr, i, size);
}
// 堆排序
void heap_sort(int* arr, int size)
{
build_max_heap(arr, size);
for (int i = size - 1; i > 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
max_heapify(arr, 0, i);
}
}
// 获取前k个最小元素
void get_topk_smallest(int* arr, int n, int k, int* result)
{
if (k > n) k = n;
int* heap = (int*)malloc(k * sizeof(int));
if (heap == NULL) {
printf("内存分配失败\n");
return;
}
// 取前k个元素构建大堆
for (int i = 0; i < k; i++)
heap[i] = arr[i];
build_max_heap(heap, k);
// 遍历剩余元素
for (int i = k; i < n; i++)
{
if (arr[i] < heap[0])
{
heap[0] = arr[i];
max_heapify(heap, 0, k);
}
}
// 排序结果并输出
heap_sort(heap, k);
for (int i = 0; i < k; i++)
result[i] = heap[i];
free(heap);
}
// 生成随机数组
void generate_random_array(int* arr, int size, int min, int max)
{
srand(time(NULL));
for (int i = 0; i < size; i++)
{
arr[i] = min + rand() % (max - min + 1);
}
}
// 打印数组
void print_array(int* arr, int size)
{
for (int i = 0; i < size; i++)
{
printf("%d ", arr[i]);
if ((i + 1) % 10 == 0)
printf("\n");
}
printf("\n");
}
// 验证结果正确性(通过全排序对比)
void verify_result(int* arr, int n, int k, int* topk)
{
// 创建数组副本并排序
int* copy = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
copy[i] = arr[i];
heap_sort(copy, n); // 注意:这里堆排序是升序
printf("\n验证结果(前10个最小元素):\n");
printf("算法结果:");
for (int i = 0; i < k; i++)
printf("%d ", topk[i]);
printf("\n正确结果:");
for (int i = 0; i < k; i++)
printf("%d ", copy[i]);
printf("\n");
// 检查是否一致
int correct = 1;
for (int i = 0; i < k; i++)
{
if (topk[i] != copy[i])
{
correct = 0;
break;
}
}
printf("验证结果:%s\n", correct ? "正确" : "错误");
free(copy);
}
int main()
{
const int N = 10000; // 数据总量
const int K = 10; // 要找的最小元素个数
int* arr = (int*)malloc(N * sizeof(int));
int* topk = (int*)malloc(K * sizeof(int));
// 生成10000个1到100000之间的随机数
generate_random_array(arr, N, 1, 100000);
printf("已生成10000个随机数\n");
// 计算前10个最小元素
clock_t start = clock();
get_topk_smallest(arr, N, K, topk);
clock_t end = clock();
// 输出结果
printf("\n最小的前10个数(升序排列):\n");
print_array(topk, K);
// 输出耗时
double time_spent = (double)(end - start) / CLOCKS_PER_SEC;
printf("计算耗时:%.6f秒\n", time_spent);
// 验证结果
verify_result(arr, N, K, topk);
// 释放内存
free(arr);
free(topk);
return 0;
}
运行结果:
结束语
经过上节堆的学习,这一节我们对于堆的Top K问题的学习与理解相对会轻松很多。
感谢您的三连支持!!!
相关文章:
[数据结构——lesson10.2堆排序以及TopK障碍]
[数据结构——lesson10.2堆排序以及TopK障碍]pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !im…...
终端里跑图形应用「GitHub 热点速览」
上周,依旧是“AI Everywhere”的热闹景象,但真正刷屏与引发讨论的,还是那些把老问题拆开、把想象力落到工程实践里的开源项目。本期上榜的 Term.Everything 把原本只能在桌面环境运行的 GUI 应用“压缩”进终端,重新定义终端(Terminal)的边界。Hyperswitch 用一套高性能网…...
trl ppo
https://www.cnblogs.com/lemonzhang/p/17829326.htmlhttps://blog.csdn.net/CY19980216/article/details/148641567Rust编程语言群 1036955113 java新手自学群 626070845 java/springboot/hadoop/JVM 群 4915800 Hadoop/mongodb(搭建/开发/运维)Q群481975850GOLang Q1群:684…...
PHP-FPM 深度调优指南 告别 502 错误,让你的 PHP 应用飞起来
PHP-FPM 深度调优指南 告别 502 错误,让你的 PHP 应用飞起来 理解 PHP-FPM 请求流程、进程池大小调整,以及防止超时和 502 错误的关键设置 — 实用规则、实际案例和可直接使用的检查清单。 大多数 PHP 应用出问题,不是因为 Nginx,而是 PHP-FPM(FastCGI 进程管理器)没配好…...
RAG系统大脑调教指南:模型选择、提示设计与质量控保一本通
本文用轻松幽默的方式解密如何在RAG系统中选择、调教和监督生成模型,让它成为一个既聪明又靠谱的知识助手。从模型选择到提示工程再到质量控制,手把手教你如何避开AI的「胡言乱语」陷阱。你还记得上次问AI一个问题,它却自信满满地胡说八道的尴尬时刻吗?"嗯,根据我的分…...
智驾终局:VLA与WA的“强脑”之争
微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087智驾领域的“终场哨”尚未吹响,真正的终局属于那些能把“说话”和“想象”融合成“思考”的玩家。当理想i8在暴雨中的山区公路…...
微软2018年第四季度顶级漏洞赏金猎人榜单揭晓
微软安全响应中心公布2018年第二季度(Q4)顶级漏洞赏金猎人名单,包括按奖金金额和提交数量排名的双榜单,360 Vulcan团队多名研究员上榜,最高单笔奖金达8万美元。2018年第四季度前五名漏洞赏金猎人表彰 | MSRC博客 我们已完成2018年4月至6月的数据统计。第四季度前五名漏洞赏…...
能源汽车智能线控底盘
微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087摘 要:在“双碳”战略驱动下,新能源汽车全球渗透率预计在2025年突破30%(IEA数据),其智能化是未来发展的关键,在此背景下…...
Linux中的LED子专业的系统
Linux中的LED子专业的系统pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-size…...
DP 凸性优化:wqs 二分
重构版:wqs 二分。发现自己阅读量最高的 wqs二分 有点简略,而且有些地方是错的,所以就重构了一下,并加入了更多的例题。 前面基本上都是照搬的原来那篇文章。介绍 wqs 二分最初由王钦石在他的 2012 年国家集训队论文中提出,也叫"带权二分",或者"dp凸优化&…...
浦东再添一所一流高校,上海交通大学医学院浦东校区正式启用
微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087 9月12日,上海交通大学医学院浦东校区正式启用,浦东再添一所一流高校。 添加图片注释,不超过 140 字(可选)浦东校区的启用…...
nccl study
https://lgd.gd/posts/2021/03/nccl/ https://blog.csdn.net/u014443578/article/details/136902252...
AI服务器公开招标大面积失败,中国联通“招”了个寂寞?
微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087为了查询三大运营商人工智能服务器的招投标信息,在工信部设立的“通信工程建设项目招标投标管理信息平台”上,搜索了一下有关…...
【GitHub每日速递 250916】2053 个 n8n 工作流曝光!365 种集成 + 可视化管理,效率直接拉满
原文:【GitHub每日速递 250916】2053个n8n工作流曝光!365种集成+可视化管理,效率直接拉满 Codebuff:开源AI编码助手,多模型协作胜Claude Code,还能深度自定义! codebuff 是一个通过终端生成代码的命令行工具。简单讲,它让你在终端里直接用AI生成代码,提升开发效率。适…...
每日一家公司职场内幕——龙旗科技(上海)
微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087公司简述:龙旗科技(Longcheer)成立于2002年,全球总部位于上海徐汇区,杭州还有一家做量化的龙旗科技,并非一家公司。龙旗…...
0129_迭代器模式(Iterator)
迭代器模式(Iterator) 意图 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。 UML 图优点简化访问接口:提供统一的遍历接口,简化客户端代码 封装内部结构:隐藏聚合对象的内部表示,提高安全性 支持多种遍历:可以在同一聚合上实现多种遍历方式 开…...
HJ7 取近似值
描述 对于给定的正实数 x,输出其四舍五入后的整数。更具体地说,若 x 的小数部分大于等于 0.5,则输出向上取整后的数;否则输出向下取整后的整数。 【提示】 不同编译器版本、不同系统环境对待实数的精度处理不同,我们建议您使用在线编译器进行调试。 输入描述: 输入一个小…...
读人形机器人13艺术领域
读人形机器人13艺术领域1. 艺术领域 1.1. 艺术始终是人类灵魂的深刻表达,是一面反映我们最深情感、思想和经历的镜子 1.2. 超越语言、文化和时间的界限,连接着不同世代的人 2. 机器人创作艺术和音乐 2.1. 如今,AI生成的艺术和音乐已不再是单纯的实验性产物,它们正逐渐成为创…...
活动报名:Voice First!Demo Day@Voice Agent Camp,9.22,上海丨超音速计划 2025
听腻了那些类比电影《Her》却无法真实落地的语音 AI 畅想?来 Demo Day@Voice Agent Camp,见证 「Voice First」理念下,真正创意和商业潜力兼具的初创项目。9 月 22 日下午,上海西岸数字谷,欢迎加入我们,一同重塑人机实时互动体验。demo 项目均来自「超音速计划 2025Voice…...
Windows计算器:现代C++实现的多功能计算工具
Windows计算器是一个用C++和C#编写的现代Windows应用程序,提供标准、科学和程序员计算功能,以及各种单位换算和货币转换功能,采用高精度算术运算确保计算准确性。项目标题与描述 Windows计算器是一个现代化的Windows应用程序,使用C++和C#编写,预装在Windows操作系统中。该…...
使用 PySide6/PyQt6 实现系统图标的展示与交互
在 Python 桌面应用开发中,系统图标的展示与选择是提升用户体验的重要环节。PySide6 和 PyQt6 作为 Qt 框架的 Python 绑定,提供了 QFileIconProvider 等核心类来实现这一功能。本文将以代码实例演示如何在两个框架中实现系统图标的可视化呈现与交互处理。 基础环境搭建与核心…...
如何让Java的线程池顺序执行任务 ?
一、基础概念 Java中的线程池本身并不提供内置的方式来保证任务的顺序执行的,因为线程池的设计目的是为了提高并发性能和效率,如果顺序执行的话,那就和单线程没区别了。 但是如果被问到想要实现这个功能该怎么做,有以下两种方式 1、使用单线程线程池 我们可以使用 SingleTh…...
Git 提交排除文件夹方法总结
在 Git 中排除某个文件夹(使其不被提交到远程仓库)有几种方法。以下是主要的解决方案:方法一:使用 .gitignore 文件(推荐) 这是最标准的方法,适用于大多数情况。创建或编辑 .gitignore 文件:# 如果还没有 .gitignore 文件 touch .gitignore在 .gitignore 中添加要排除的…...
如何在 Ubuntu24.04 TLS 上安装 Kubernetes 集群 - Antonie
0-先决条件 在开始安装之前,请确保您的环境满足以下先决条件:Ubuntu 24.04 LTS 系统。 至少 4GB RAM 或更多。 至少 2 个 CPU 内核。 有 40 GB 可用磁盘空间。1- 环境准备 集群规划k8s-node-1(Master):10.15.0.132 k8s-node-2(Worker):10.15.0.133 k8s-node-3(Worker)…...
Jmeter的插件开发
一、Jmeter的启动流程 在说启动流程之前我们先来看看Jmeter源码的各个重要的包:components—包含与协议无关的组件,如可视化、断言等等。 core —JMeter的核心代码,包括所有的核心接口和抽象类。 examples —演示采样器如何使用新bean框架的例子(开发插件前可以好好看看该包…...
Educational Codeforces Round 182 (Rated for Div. 2)
A. Cut the Array 题意:把数组分成三段,使得每段和模\(3\)后的值都相同或者都不相同。 \(n\)很小,暴力枚举分段就行了。点击查看代码 #include <bits/stdc++.h>using i64 = long long;void solve() {int n;std::cin >> n;std::vector<int> a(n);for (int …...
java第二周课前提问
一、代码引入 public class Main {static void changeStr(String x) {x = "xyz";}static void changeArr(String[] strs) {for (int i = 0; i < strs.length; i++) {strs[i] = strs[i]+""+i;}}public static void main(String[] args) { String x = …...
java GC
java GC...
Redis最佳实践——性能优化技巧之监控与告警详解
一、监控体系构建1. 核心监控指标矩阵指标类别 关键指标 计算方式/说明 健康阈值(参考值)内存相关 used_memory INFO Memory 获取 不超过 maxmemory 的 80%mem_fragmentation_ratio 内存碎片率 = used_memory_rss / used_memory 1.0-1.5命中率 keyspace_hits INFO Stats 获取…...
week1
任务一,编码规范: 我在网上找到了华为公司C++编码规范,我摘下几点我觉得我应该注意的 1、程序块要采用缩进风格编写, 缩进的空格数为4个 2、不允许把多个短语句写在一行中, 即一行只写一条语句 3、 if、for、do、while、case、switch、default等语句自占一行, 且if、for、do…...
EF Core 与 MySQL:迁移和关系配置详解
EF Core 与 MySQL:迁移和关系配置详解 1. EF Core 中的关系类型 Entity Framework Core 支持三种主要的关系类型: 一对一关系 (One-to-One) 一个实体实例只与另一个实体实例相关联。例如:一个用户有一个用户资料。csharppublic class User {public int Id { get; set; }pub…...
《原子习惯》-读书笔记2
2025.09.15 Day2 1、目标和体系有什么不同?我最初是从“呆伯特漫画”的创作者斯科特亚当斯(Scott Adams)那里了解到两者的区别的。目标是关于你想要达到的结果,而体系是涉及导致这些结果的过程。2、争取每天都有进步是你走向成功唯一的方法。3、如果你想要得到更好的结果,那…...
CF1626D 题解
CF1626D 题解 貌似题解区没有这种解法。 题面 CF1626D Martial Arts Tournament - 洛谷 (luogu.com.cn) 思路 问题就是把 \(a\) 分成 \(3\) 个子集(可以为空),每两个子集里的数并不重复,把每个子集的大小补到 \(2^x\) 最少要补的数的个数。 先把 \(a\) 给排序,那么就可以转…...
Python 集合运算:并集、交集、差集全解析
在 Python 中,集合(set)是一种无序的、不包含重复元素的数据结构。集合提供了丰富的运算方法,包括并集、交集、差集等。这些运算在数据处理、数学计算和算法设计中非常实用。今天,就让我们一起深入学习 Python 集合的运算方法,并通过实例代码展示它们的使用。 一、集合的…...
第一周数据可视化作业
一、个人介绍 My name is Ou Qi. (🙂) 我性格阳光开朗,始终保持着对学习的热忱和对未知事物的探索欲,尤其从小就对数学有着浓厚兴趣 —— 课堂上会紧跟老师的思路深度思考,课后也常主动琢磨题型、尝试举一反三,在不断推导中把知识学扎实。 二、我的专业选择与学习历程 步…...
用 C++ + OpenCV + Tesseract 实现英文数字验证码识别
本文展示如何用 C++ 结合 OpenCV 做图像预处理,再调用 Tesseract OCR 识别验证码。适用于希望在高性能后端或本地服务里集成 OCR 的场景。方案包含: 更多内容访问ttocr.com或联系1436423940 环境与依赖安装 图像预处理(灰度、二值化、形态学去噪、放大) 使用 Tesseract API…...
java 第一节课课前提问
一、使用Java能编写的程序 企业级后端应用 Java 在企业级开发中占据重要地位,常被用于构建大型服务器端应用,如电商平台、银行交易系统、CRM(客户关系管理)系统等。这类应用通常需要处理高并发、复杂业务逻辑和海量数据,Java 凭借稳定的性能、丰富的企业级框架(如 Spring…...
二进制解码器、选通器和分配器
二进制解码器 3比特的二进制解码器可以由下图表示。每种组合方式对应着解码器的不同输出。3-8解码器可以用三个非门和三个与门构成解码器可以拼接起来组成更大的解码器,比如两个3-8解码器可以拼起来组成一个4-16解码器。选通器和分配器。 选通器 一个8选1的选通器如下图所示。…...
2025最新版 Photoshop软件免费下载安装完整教程(PS2025)超详细安装教程
Adobe Photoshop 2025 凭借升级的 AI 编辑功能、更优的图像处理效率,成为设计与摄影领域的热门工具。但不少用户在安装时,易因路径选择、安全软件拦截等问题卡壳。本教程聚焦安装全流程,从前期准备到后续配置,用清晰步骤帮你避开误区,顺利完成安装,快速解锁 PS 2025 的创…...
nac一键卸载软件脚本
将下面的代码保存为uninstall.sh: echo delete shit.app..need your root pwd; sudo rm -rf /Applications/dvc-manageproxy-exe.app; sudo rm -rf /Applications/LVSecurityAgent.app; echo script is fighting...; sudo chflags noschg /opt/LVUAAgentInstBaseRoot; sudo chf…...
交叉编译openharmony版本的openssh
sudo mkdir /systemsudo chmod 777 /system/export CC=aarch64-linux-gnu-gcc编译zlib./configure --prefix=/systemmake && make install 编译openssl./config linux-aarch64 --prefix=/system/ --openssldir=/system/etc/ssl --libdir=…...
为什么不建议在 Docker 中跑 MySQL
前言 今天我们来聊聊一个很有趣的话题:为什么我不建议在Docker中运行MySQL数据库? 有些小伙伴在工作中可能为了部署方便,习惯将所有组件都容器化,但数据库真的适合放在容器里吗? 今天就专门跟大家一起聊聊这个话题,希望对你会有所帮助。 一、容器化与数据库:天生的矛盾?…...
CFD
算例汇总 1、一维Sod激波管 2、二维平板 3、NACA0012 4、高马赫数喷流 5、双马赫反射 6、二维Riemann 7、二维Rayleigh-Taylor 8、TENO算例...
[MCP][05]Elicitation示例
Elicitation能让工具在关键时刻暂停执行,并向用户请求特定信息前言 如果你之前接触过LangGraph的"Human in the loop"概念,那么理解MCP的Elicitation机制就会容易很多。这两个功能非常相似,都是让AI在需要时停下来,礼貌地向人类寻求帮助或确认。 想象一下,当你正…...
Warsaw主题关闭导航条
\setbeamertemplate{headline}{}...
Python Socket网络编程(2)
进程:提供计算资源的单位 线程:真正工作的单位(cpu调度最小单元) GIL锁:全局解释器锁(是CPython解释器特有的,平时说的Python解释器一般都是CPython解释器,还有GPython等等) 让一个进程中同一时刻只能有一个线程可以被CPU调动。所以Python中应该是没有严格意义的多线程…...
PS2025安装包下载及PS2025安装包安装教程详细步骤(包含安装包下载链接)
在图像处理领域,Adobe Photoshop 一直占据着举足轻重的地位,而 PS 2025 更是汇聚前沿技术与实用功能,成为众多设计师与图像处理爱好者的得力工具。但初次安装这款软件,可能会因步骤繁杂、细节众多而让人感到棘手。别担心,本教程将以清晰、简洁的方式,带你一步步完成 PS 2…...
Nature Genetics | 本周最新文献速递
Multiancestry brain pQTL fine-mapping and integration with genome-wide association studies of 21 neurologic and psychiatric conditions 中文标题: 多祖先脑蛋白遗传调控解码!pQTL精细映射揭示神经精神疾病机制 关键词: 脑蛋白定量性状位点、精细映射、多祖先整合、…...
关于go里切片作为函数参数时是引用传递还是值传递
go语言中切片参数的值传递问题问题起因 写一道回溯算法题,把ans二维数组作为函数参数传入,想在函数里面,不停地append,最后返回ans 实际发现ans打印出来是空的,就很奇怪,因为我是事先分配好空间的,理论上不会发生扩容,底层数组是共用的,咋回事 func permute(nums []in…...
DRAN读写循环
DRAM读写循环 以一个8 * 8 的二维阵列为例子,假设部分存储单元为1,部分为0,现在要读写其中某一个cell的值。为了确定存储的位置,我们需要内存地址,为了传输内存地址,我们需要地址总线。8 * 8阵列一共有64个cell,我们需要6线地址总线,一共能表示64种二进制值。三根地址总…...