【数据结构】堆和priority_queue
堆的定义
堆是什么?实际上堆是一种特殊的(受限制的)完全二叉树,它在完全二叉树的基础上要求每一个节点都要大于等于或者小于等于它的子树的所有节点。这个大于小于体现在节点的值或者权重。
如图所示:
根节点大于等于子树中所有节点的堆叫做大顶堆(大根堆)
根节点小于等于子树中所有节点的堆叫做小顶堆(小根堆)
堆的存储
堆属于完全二叉树,因此使用二叉树的顺序存储结构来存储堆是最优的。
堆的核心操作(默认以大根堆为标准)
向上调整算法
一般使用背景:
在堆的最后面插入一个元素之后,要将这个节点调整到正确的位置。
流程:
将该节点的值直接与父节点相比较,如果比父节点大就要与父节点交换。重复此步骤一直到比父节点小 或者 已经换到了根节点,就完成了向上调整,此时这个新来的节点就已经被调整到了正确的位置。
注意事项:
向上调整算法就是子节点要跟父节点换,一个子节点的父节点只有一个,所以直接交换即可。
代码实现
//向上调整
void up(int child) //传入要调整的节点的下标(下标具有唯一性,堆中允许节点的值相同)
{int parent = child / 2;while(parent >= 1 && heap[child] > heap[parent]) // 这里必须是parent >= 1 ,不能是parent > 1 。 parent > 1时,如果该节点是最大的,那么只能被调整到堆顶的子节点的位置。{swap(heap[child],heap[parent]);//被换掉的那个元素就不管了,它已经在正确的位置上了,现在我们要更新child节点 ,然后再由公式得出parent节点 child = parent;parent = child / 2;}
}
向下调整算法
一般使用背景:
先了解堆pop()的原理是什么?
堆pop()删除堆顶元素的逻辑是将目前的堆顶元素与堆的最后一个元素交换,然后将堆的大小-1,这样就访问不到最后的那个元素了(原来的堆顶元素)。
在删除堆顶元素之后,本身在最后位置的元素来到了堆顶(根部),这时候的堆只有左右子树是合法的,整体是不合法的,所以就要进行向下调整算法,将目前的堆顶元素调整到正确的位置。
流程:
将要向下调整的节点的值与两个子节点中最大的那个值相比较,如果该节点的值比子节点的最大值要小,就交换。重复此步骤,直到该节点的值比子节点的最大值大 或者 已经被换到了叶子节点,那么此时该节点就被调整到了正确的位置。
注意事项:
向下调整算法是父节点要跟子节点换,一个父节点最多有两个子节点,所以我们要找出最大的那个子节点作比较。
代码实现
//向下调整
void down(int parent)
{int child = parent * 2; //先默认指向左节点 思考:child是两倍的parent得到的,这个时候有没有可能超出了n呢?所以要先判断child是否存在 while(child <= n) //孩子存在才有下文 {if(child + 1 <=n && heap[child] < heap[child + 1]) child++;if(heap[parent] >= heap[child]) return; //heap[parent] >= heap[child]比heap[parent] > heap[child]少走一步,但都是正确的swap(heap[parent],heap[child]);parent = child;child = parent * 2;}
}
堆的模拟实现
//默认建大根堆
#include <iostream>
using namespace std;const int N = 1e6 + 10;
int n,heap[N]; //n用来记录heap存放的有效元素个数,heap用来存储堆的数据,父子关系是靠公式计算得来(堆是完全二叉树) //向上调整
void up(int child)
{int parent = child / 2;while(parent >= 1 && heap[child] > heap[parent]){swap(heap[child],heap[parent]);child = parent;parent = child / 2;}
}//向下调整
void down(int parent)
{int child = parent * 2; while(child < n) {if(heap[child] < heap[child + 1]) child++;if(heap[parent] >= heap[child]) return;swap(heap[parent],heap[child]);parent = child;child = parent * 2;}
}void push(int x)
{heap[++n] = x; //最刚开始n=0,存入第一个元素的时候++n,是在1的位置存入,0的位置没有任何元素 up(n);
}void pop()
{swap(heap[1],heap[n]);n--;down(1); //要搞清楚堆的根存放在哪里
}int size()
{return n;
}int top()
{return heap[1];
}int main()
{int a[10] = {1, 41, 23, 10, 11, 2, -1, 99, 14, 0};for(int i=0;i<sizeof(a)/sizeof(int);i++){push(a[i]);}while(size()){cout << top() << " ";pop();}return 0;
}
运行结果:
注意:这个top实际上是有bug的,就是在没有元素的时候是不能调用这个接口的,这样的条件检查我们不在函数内实现,而是在调用前进行检查。同样的,有一个在做题时遇到的小细节值得注意,也是关于栈中top接口的调用。
题外话
P4387 【深基15.习9】验证栈序列
题目描述
给出两个序列 pushed 和 poped 两个序列,其取值从 1 到 n ( n ≤ 100000 ) n(n\le100000) n(n≤100000)。已知入栈序列是 pushed,如果出栈序列有可能是 poped,则输出 Yes
,否则输出 No
。为了防止骗分,每个测试点有多组数据,不超过 5 5 5 组。
输入格式
第一行一个整数 q q q,询问次数。
接下来 q q q 个询问,对于每个询问:
第一行一个整数 n n n 表示序列长度;
第二行 n n n 个整数表示入栈序列;
第三行 n n n 个整数表示出栈序列;
输出格式
对于每个询问输出答案。
输入输出样例 #1
输入 #1
2
5
1 2 3 4 5
5 4 3 2 1
4
1 2 3 4
2 4 1 3
输出 #1
Yes
No
这是我当时的代码:
#include<iostream>
#include<stack>
using namespace std;const int N = 1e5 + 10;
int in[N],out[N];int main()
{ int q;cin >> q;while(q--){stack<int> st; //栈必须放在循环内,要不然每次重新接受数据前要清空栈元素 int n;cin >> n;for(int i=1;i<=n;i++) cin >> in[i]; for(int i=1;i<=n;i++) cin >> out[i];int t = 1; //t指针指向out的第一个元素 for(int i=1;i<=n;i++){st.push(in[i]);while(t <= n && st.top() == out[t] && st.size()) //t <= n不能丢,要不然两个序列完全匹配的时候t就会加到n+1,那样就死循环了 {st.pop(); t++;}}if(st.size()) cout << "No" << endl;else cout << "Yes" << endl;}return 0;
}
看起来似乎没有问题,但是当时一直报错 runtime error ,我也不知道错在哪,到最后才注意到, while() 语句中用 && 连接的连续条件判断是从左到右执行的,在 st.top() 调用之前应该确保栈不为空,所以 st.size() 的检查一定要放在 st.top() == out[t] 的前面。
使用 &&(逻辑与)连接的多个条件判断是有顺序的,这与 C++ 的短路求值(short-circuit evaluation)机制有关。
C++ 在使用 && 连接多个条件时,会从左到右依次评估每个条件表达式。如果左侧的条件已经为 false,则右侧的条件表达式不会被求值,因为无论右侧条件是什么,整个 && 表达式的结果都会是 false。这种行为被称为短路求值。
int a = 0;
int b = 5;while (a != 0 && b / a > 1) {// do something
}
在这个例子中,a != 0 会被首先评估。如果 a 为 0,b / a > 1 这一部分的表达式将不会被求值,避免了除以零的错误。&& 运算符是有顺序的,并且遵循短路求值规则。左侧条件为 false 时,右侧条件不会被求值。
priority_queue
普通的队列是先进先出(FIFO)的结构,priority_queue是一种基于堆实现的优先级队列,priority_queue中的元素都是有优先级的,它在插入元素时,即使是在队尾插入,也会根据优先级调整到相对应的位置,优先级越高越靠近队头的位置。同样删除元素也是删除优先级最高的元素。
priority_queue 的模板定义
priority_queue 的模板定义如下:
template <class T, class Container = std::vector<T>, class Compare = std::less<T>>
class priority_queue;
T:存储的数据类型(如 int)。
Container:底层存储结构,默认是 std::vector(但也可以用 std::deque 等)。
Compare:比较函数对象,决定优先级顺序,默认是 std::less(最大堆)。
默认是 大根堆,std::less 表示大的值优先,std::greater 表示小的值优先。
就是这个比较反人性,跟常规的比较函数是反过来的。
简单创建priority_queue(这样创建默认是大根堆)
#include<iostream>
#include<queue>using namespace std;int main()
{priority_queue<int> heap; //默认大根堆int a[10] = {1, 41, 23, 10, 11, 2, -1, 99, 14, 0};for(int i=0;i<sizeof(a)/sizeof(int);i++){heap.push(a[i]);}while(heap.size()){cout << heap.top() << " ";heap.pop();}return 0;
}
运行结果:
创建基本数据类型的优先级队列(可将int替换成其他基本数据类型)
#include<iostream>
#include<queue>using namespace std;int a[10] = {1, 41, 23, 10, 11, 2, -1, 99, 14, 0};void test1()
{//priority_queue<数据类型,实现结构,排序方式>//大根堆 priority_queue<int,vector<int>,less<int>> heap1;//小根堆 priority_queue<int,vector<int>,greater<int>> heap2;for(int i=0;i<10;i++){heap1.push(a[i]); } while(heap1.size()){cout << heap1.top() << " ";heap1.pop(); }cout << endl; for(int i=0;i<10;i++){heap2.push(a[i]); } while(!heap2.empty()){cout << heap2.top() << " ";heap2.pop(); }
} int main()
{test1();return 0;
}
运行结果:
创建结构体数据类型的优先级队列
当 priority_queue 存储的是 结构体 而不是基本类型,C++ 不会默认知道如何比较结构体的优先级。因此我们必须提供比较方式,否则会导致编译错误。
方式一:重载运算符operator<
#include <iostream>
#include <queue>
#include <vector>struct Person {std::string name;int age;// 重载 < 运算符,默认用于 std::priority_queuebool operator<(const Person& other) const {return age < other.age; // 年龄大的优先级更高(最大堆)}
};int main() {std::priority_queue<Person> pq;pq.push({"Alice", 25});pq.push({"Bob", 30});pq.push({"Charlie", 20});while (!pq.empty()) {std::cout << pq.top().name << " " << pq.top().age << std::endl;pq.pop();}return 0;
}
运行结果:
方式二:使用自定义比较函数
可以提供一个 自定义比较函数 作为 priority_queue 的第三个模板参数。
这时 priority_queue 的第三个参数的定义:class Compare = std::less ,要求传入的是一个类型,而不是普通函数,所以这个比较函数必须是一个可调用对象。那么自定义比较函数 不能是普通函数,而一般需要使用结构体(仿函数)或 lambda 表达式。
#include <iostream>
#include <queue>
#include <vector>struct Person {std::string name;int age;
};// 自定义比较仿函数
struct ComparePerson {bool operator()(const Person& a, const Person& b) {return a.age > b.age; // 年龄小的优先级更高(最小堆)}
};int main() {std::priority_queue<Person, std::vector<Person>, ComparePerson> pq;pq.push({"Alice", 25});pq.push({"Bob", 30});pq.push({"Charlie", 20});while (!pq.empty()) {std::cout << pq.top().name << " " << pq.top().age << std::endl;pq.pop();}return 0;
}
方式三:使用 Lambda 表达式
C++11 之后,可以用 lambda 来替代仿函数。
如果 不想写额外的比较结构体,可以直接使用 Lambda 作为比较函数:
#include <iostream>
#include <queue>
#include <vector>struct Person {std::string name;int age;
};int main() {// Lambda 比较函数auto cmp = [](const Person& a, const Person& b) {return a.age > b.age; // 年龄小的优先级更高(最小堆)};std::priority_queue<Person, std::vector<Person>, decltype(cmp)> pq(cmp);//decltype(cmp) 自动推导 Lambda 类型pq.push({"Alice", 25});pq.push({"Bob", 30});pq.push({"Charlie", 20});while (!pq.empty()) {std::cout << pq.top().name << " " << pq.top().age << std::endl;pq.pop();}return 0;
}
相关文章:
【数据结构】堆和priority_queue
堆的定义 堆是什么?实际上堆是一种特殊的(受限制的)完全二叉树,它在完全二叉树的基础上要求每一个节点都要大于等于或者小于等于它的子树的所有节点。这个大于小于体现在节点的值或者权重。 如图所示: 根节点大于等于…...
Vue的简单入门 三
目录 侦听器 watch 注意 表单输入绑定 v-model v-model修饰符编辑 lazy number Trim 模板引用 组件组成 组件引用三步走 组件的嵌套关系 header Main Aside Aritice Item App.vue组件引入三个子组件 组件的注册方式 全局注册组件的方法 (1) Vue 2 语…...
kotlin的val声明的变量是常量吗
kotlin的val声明的变量是常量吗 DeepSeek R1 思考 65 秒 思考过程 嗯,用户问的是Kotlin中的val声明的变量是不是常量。首先我需要回忆一下Kotlin的基础知识。记得在Kotlin里,val用来声明只读变量,也就是说一旦赋值之后就不能再重新赋值了。…...
C# | 委托 | 事件 | 异步
委托(Delegate)和事件(Event) 在C#和C中,委托(Delegate)与事件(Event)以及函数对象(Function Object)是实现回调机制或传递行为的重要工具。虽然…...
算法日记33:14届蓝桥C++B冶炼金属(二分答案)
一、题目: 二、题解: 1、思路解析: 1)首先我们可以发现题目的样例数量为( n < 1000 n<1000 n<1000),因此我们可以考虑 O ( n ∗ l o g n ) O(n*log^n) O(n∗logn)时间复杂度的算法 …...
【YOLO V5】目标检测 WSL2 AutoDL VScode SSH
【YOLO V5】目标检测 WSL2 AutoDL VScode SSH 前言整体思路理解向YOLO 目标检测完整流程 环境配置Anaconda 获取 YOLO 代码与预训练模型下载 YOLOv5 代码和预训练模型配置 YOLOV5 工程环境解压 YOLOv5 源代码 并 添加预训练模型调整依赖版本选择对应的 Python 解释器 数据集准备…...
前端基础之ajax
vue-cli配置代理服务器解决跨域问题 我们可以使用一个代理服务器8080,Vue项目8080发送请求向代理服务器8080发送请求,再由在理服务器转发给后端服务器 首先需要在vue.config.js中配置代理服务器 const { defineConfig } require(vue/cli-service) modul…...
vscode离线配置远程服务器
目录 一、前提 二、方法 2.1 查看vscode的commit_id 2.2 下载linux服务器安装包 2.3 安装包上传到远程服务器,并进行文件解压缩 三、常见错误 Failed to set up socket for dynamic port forward to remote port(vscode报错解决方法)-C…...
C语言——string.h下的特殊库函数
string.h下的特殊函数 strtok(分割字符串)strerror(错误码信息)memcpy(拷贝)memmove(拷贝)memset(设置内存)memcmp(比较大小) strtok(分割字符串) char * strtok ( char * str, const char * s…...
烟花燃放安全管控:智能分析网关V4烟火检测技术保障安全
一、方案背景 在中国诸多传统节日的缤纷画卷中,烟花盛放、烧纸祭祀承载着人们的深厚情感。一方面,烟花璀璨,是对节日欢庆氛围的热烈烘托,寄托着大家对美好生活的向往与期许;另一方面,袅袅青烟、点点烛光&a…...
【一个月备战蓝桥算法】递归与递推
字典序 在刷题和计算机科学领域,字典序(Lexicographical order)也称为词典序、字典顺序、字母序,是一种对序列元素进行排序的方式,它模仿了字典中单词的排序规则。下面从不同的数据类型来详细解释字典序: …...
二、Java-封装playwright UI自动化(根据官网执行步骤,首先封装BrowserFactory枚举类及BrowserManager)
前言 查看playwright官网,api文档了解到,playwright的基本步骤: 1、实例化一个playwright 2、启动一个浏览器类型 3、打开一个页面 所以,在封装时需要有一个浏览器工厂类,定义不同的浏览器类型,在配置文…...
java项目之基于ssm的在线视频网站开发(源码+文档)
项目简介 基于ssm的在线视频网站开发实现了以下功能: 该系统的目标用户包括管理员,用户。管理员上传视频,管理视频,查看视频留言,回复视频留言,管理视频收藏信息,管理公告,管理用户…...
观察者模式的C++实现示例
核心思想 观察者模式是一种行为型设计模式,定义了对象之间的一对多依赖关系。当一个对象(称为Subject,主题)的状态发生改变时,所有依赖于它的对象(称为Observer,观察者)都会自动收到…...
c语言中的主要知识点
一、基础语法与结构 程序结构 包含顺序结构、选择结构(if/switch)、循环结构(for/while/do-while)。 程序必须包含且仅有一个main函数作为入口。 数据类型与变量 基本类型:整型(int、long)、浮…...
Pytorch构建LeNet进行MNIST识别 #自用
LeNet是一种经典的卷积神经网络(CNN)结构,由Yann LeCun等人在1998年提出,主要用于手写数字识别(如MNIST数据集)。作为最早的实用化卷积神经网络,LeNet为现代深度学习模型奠定了基础,…...
docker:Dockerfile案例之自定义centos7镜像
1 案例需求 自定义centos7镜像。要求: 默认登录路径为 /usr可以使用vim 2 实施步骤 编写dockerfile脚本 vim centos_dockerfile 内容如下: #定义父镜像 FROM centos:7#定义作者信息 MAINTAINER handsome <handsomehandsome.com># 设置阿里云…...
post get 给后端传参数
post 方式一 : data: params 作为请求体(Request Body)传递: 你已经展示了这种方式,通过data字段直接传递一个对象或数组。这种方式通常用于传递复杂的数据结构。dowmfrom: function (params) { return request({ u…...
Linux 系统不同分类的操作命令区别
Linux 系统有多种发行版,每种发行版都有其独特的操作命令和工具。以下是一些常见的分类及其操作命令的区别: 1. 基于 Red Hat 的发行版 (RHEL, CentOS, Fedora) 1.1 包管理 安装软件包: bash复制 sudo yum install <package> 更新软件包: bash复制 sudo yum update…...
Checkpoint 模型与Stable Diffusion XL(SDXL)模型的区别
Checkpoint 模型与 Stable Diffusion XL(SDXL)模型 在功能、架构和应用场景上有显著区别,以下是主要差异的总结: 1. 基础架构与定位 Checkpoint 模型 是基于 Stable Diffusion 官方基础模型(如 SD 1.4/1.5)…...
软件工程与实践(第4版 新形态) 练习与实践1
软件工程与实践(第4版 新形态) 练习与实践1 1.填空题 (1)程序,文档 (2)系统软件,支撑软件,应用软件 (3)系统方法 (4)软件开发和维护 (5)工程的概念、原理、技术和方法 (6)实现软件的优质高产 (7)软件开发技术和…...
探秘基带算法:从原理到5G时代的通信变革【九】QPSK调制/解调
文章目录 2.8 QPSK 调制 / 解调简介QPSK 发射机的实现与原理QPSK 接收机的实现与原理QPSK 性能仿真QPSK 变体分析 本博客为系列博客,主要讲解各基带算法的原理与应用,包括:viterbi解码、Turbo编解码、Polar编解码、CORDIC算法、CRC校验、FFT/…...
侯捷 C++ 课程学习笔记:深入理解智能指针
文章目录 每日一句正能量一、引言二、智能指针的核心概念(一)std::unique_ptr(二)std::shared_ptr(三)std::weak_ptr 三、学习心得四、实际应用案例五、总结 每日一句正能量 如果说幸福是一个悖论ÿ…...
基于Qwen-VL的手机智能体开发
先上Demo: vl_agent_demo 代码如下: 0 设置工作目录: 你的工作目录需要如下: 其中utils文件夹和qwenvl_agent.py均参考自 GitHub - QwenLM/Qwen2.5-VL: Qwen2.5-VL is the multimodal large language model series developed by …...
系统盘还原成正常U盘
选择格式化,等格式化完毕就完了 点击还原设备的默认值格式化就完了...
Leetcode 103: 二叉树的锯齿形层序遍历
Leetcode 103: 二叉树的锯齿形层序遍历 问题描述: 给定一个二叉树,返回其节点值的锯齿形层序遍历(即第一层从左到右,第二层从右到左,第三层从左到右,依此类推)。 适合面试的解法:广…...
FastGPT 引申:基于 Python 版本实现 Java 版本 RRF
文章目录 FastGPT 引申:基于 Python 版本实现 Java 版本 RRF函数定义使用示例 FastGPT 引申:基于 Python 版本实现 Java 版本 RRF 函数定义 使用 Java 实现 RRF 相关的两个函数:合并结果、过滤结果 import java.util.*;// 搜索结果类型定义…...
C++中的无锁编程
引言 在当今多核处理器普及的时代,并发编程已成为高性能应用程序开发的关键技术。传统的基于锁的同步机制虽然使用简单,但往往会带来性能瓶颈和死锁风险。无锁编程(Lock-Free Programming)作为一种先进的并发编程范式,…...
【全栈开发】---- 一文掌握 Websocket 原理,并用 Django 框架实现
目录 介绍 底层原理 握手环节详解: 收发数据(加密) Django 中配置 channels 1、注册 channels 2、在 settings.py 中添加 asgi_application 3、修改 asgi.py 文件 4、routing 5、consumers 实现 聊天室 介绍 WebSocket是一种先进的通信协议&…...
游戏引擎学习第135天
仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾 game_asset.cpp 的创建 在开发过程中,不使用任何现成的游戏引擎或第三方库,而是直接基于 Windows 进行开发,因为 Windows 目前仍然是游戏的标准平台,因此首先在这个环境中进行…...
国内支持Stable Diffusion模型的平台
国内支持Stable Diffusion模型的平台 截至2025年3月,国内支持SD模型的平台主要包括以下六类,覆盖不同用户需求和技术层级: 一、模型分享与下载平台 Liblib.ai 描述:国内最大SD原创模型社区,提供海量基础模型、Lora…...
扣子(Coze):重构AI时代的工作流革命
文章目录 扣子(Coze):重构AI时代的工作流革命使用Coze:一、工作流的本质:从单点智能到系统智能二、扣子工作流的技术基因三、场景化实践:从知识库到智能员工四、未来图景:AI Agent的进化之路结语…...
alloc、malloc 与 allocator:内存管理三剑客
内存管理是C语言开发者的核心能力,也是系统级编程的基石。 一、内存分配三剑客:malloc/calloc/realloc 1. malloc函数原理 int* arr (int*)malloc(5 * sizeof(int)); // 分配20字节空间(假设int为4字节) 从堆区分配指定字节的连…...
单细胞分析(21)——SCENIC 分析流程(singularity容器版)
SCENIC 分析流程笔记 SCENIC (Single-Cell rEgulatory Network Inference and Clustering) 是一种基于单细胞 RNA 测序数据的调控网络分析方法,主要用于识别调控因子(TFs)及其靶基因(Regulons),并评估这些…...
亚马逊云科技Marketplace(中国区)上架专业服务产品, “云生态连接器”价值凸显
近日,由西云数据运营的亚马逊云科技Marketplace(中国区)正式支持专业服务产品。此次发布将大幅简化企业对云专业服务的采购流程,实现云软件从规划、部署到支持的全生命周期管理,同时也为合作伙伴提供了更多的销售机会。…...
拉普拉斯·隆格·楞次矢量
L − R − L L-R-L L−R−L 矢量的推导 有平方反比有心力: F ⃗ − k r 2 r ^ \vec F-\dfrac{k}{r^2}\hat r F −r2kr^ 显然角动量 L ⃗ r ⃗ p ⃗ \vec L\vec r\times \vec p L r p 守恒。 故 ∣ L ⃗ ∣ Const \begin{vmatrix}\vec L\end{vmatrix}\…...
GStreamer —— 2.3、Windows下Qt加载GStreamer库后运行 - “教程3:动态管道“(附:完整源码)
运行效果(音频) 简介 上一个教程演示了GStreamer 概念。本教程中的管在它设置为 playing 状态之前完全构建。这没关系。如果 我们没有采取进一步的行动,数据会到达 pipeline 的 pipeline 和 pipeline 将生成错误消息并停止。但 我们将采取进一…...
jupyter notebook更改文件存储路径
默认情况打开是这样的 进入cmd或者Anaconda Prompt,输入以下命令 jupyter notebook --generate-config进入该目录 打开该文件,CTRLF 查找c.ServerApp.root_dir 进行修改。 这样就修改好啦!...
基于遗传算法的无人机三维路径规划仿真步骤详解
基于遗传算法的无人机三维路径规划仿真步骤详解 一、问题定义 目标:在三维空间内,寻找从起点到终点的最优路径,需满足: 避障:避开所有障碍物。路径最短:总飞行距离尽可能短。平滑性:转折角度不宜过大,降低机动能耗。输入: 三维地图(含障碍物,如立方体、圆柱体)。起…...
①EtherCAT转Modbus485RTU网关多路同步高速采集无需编程串口服务器
EtherCAT转Modbus485RTU网关多路同步高速采集无需编程串口服务器https://item.taobao.com/item.htm?ftt&id798036415719 型号 1路总线EC网关 MS-A2-1011 2路总线EC网关 MS-A2-1021 4路总线EC网关 MS-A2-1041 EtherCAT 串口网关 EtherCAT 转 RS485 技术规格 …...
Spring Boot WebFlux 中 WebSocket 生命周期解析
Spring Boot WebFlux 中的 WebSocket 提供了一种高效、异步的方式来处理客户端与服务器之间的双向通信。WebSocket 连接的生命周期包括连接建立、消息传输、连接关闭以及资源清理等过程。此外,为了确保 WebSocket 连接的稳定性和可靠性,我们可以加入重试…...
集合论之集合的表示法
目录 1. 说明 2. 常用表示法 2.1 枚举法(Roster Notation) 2.2 构建法(Set-builder notation) 3. 其它表示法 1. 说明 要表示一个集合,可以直接列出其元素,或者提供一种可以唯一地刻画其元素的方当。 2. 常用表示法 2.1 枚举法(Roster Notatio…...
【C语言】值传递与指针传递,以及 `.` 和 `->` 操作详解
在 C 语言中,函数参数的传递机制和结构体成员的访问方式是编程中的核心概念。值传递(pass-by-value)和指针传递(pass-by-pointer)决定了函数如何处理传入的数据,而 . 操作符 和 -> 操作符 则是访问结构体成员的两种主要工具。这两者密切相关,尤其在处理结构体时,它们…...
机器人训练环境isaac gym以及legged_gym项目的配置问题
完整的安装环境教程(强烈推荐):...
DeepSeek 开源周回顾「GitHub 热点速览」
上周,DeepSeek 发布的开源项目用一个词形容就是:榨干性能!由于篇幅有限,这里仅列出项目名称和简介,感兴趣的同学可以前往 DeepSeek 的开源组织页面,深入探索每个项目的精彩之处! 第一天 FlashML…...
冯 • 诺依曼体系结构
文章目录 冯 • 诺依曼体系结构的介绍冯 • 诺依曼体系结构的由来内存是如何提高冯•诺依曼体系结构效率的?为什么程序运行之前必须先加载到内存?从软件层面上再理解冯 • 诺依曼体系结构(QQ聊天的数据流动)一些知识的补充 冯 • …...
软考架构师笔记-存储管理
1.5 存储管理 存储管理 页式存储组织 虚地址 页号 | 页内地址页表 页号 | 块号物理地址 块号 | 页内地址访存两次:访问页表得到物理地址,根据物理地址得到数据就是把用户程序的空间分成若干页,把内存空间分成若干块,块和页的…...
【杂谈】信创电脑华为w515(统信系统)登录锁定及忘记密码处理
华为w515麒麟芯片版,还有非麒麟芯片版本,是一款信创电脑,一般安装的UOS系统。 准备一个空U盘,先下载镜像文件及启动盘制作工具,连接如下: 百度网盘 请输入提取码 http://livecd.uostools.com/img/apps/l…...
C#实现语音合成播报器——基于System.Speech的语音交互方案,在windows上实现语音播报指定文本
——基于System.Speech的语音交互方案,在windows上实现语音播报指定文本 一、语音合成播报应用场景 语音合成播报器广泛应用于以下领域: 工业控制:生产线异常报警、设备状态实时播报(如网页4中的WinCC语音报警插件)…...
【数据库】关系代数
关系代数 一、关系代数的概念二、关系代数的运算2.1 并、差、交2.2 投影、选择2.3 笛卡尔积2.4 连接2.5 重命名2.6 优先级 一、关系代数的概念 关系代数是一种抽象的数据查询语言用对关系的运算来表达查询 运算对象:关系运算符:4类运算结果:…...