Floyd算法求解最短路径问题——从零开始的图论讲解(3)
目录
前言
Djikstra算法的缺陷
为什么无法解决负权图
模拟流程
什么是Floyd算法
Floyd算法的核心思想
状态表示
状态转移方程
边界设置
代码实现
逻辑解释
举例说明
Floyd算法的特点
结尾
前言
这是笔者图论系列的第三篇博客
第一篇:
图的概念,图的存储,图的遍历与图的拓扑排序——从零开始的图论讲解(1)_图论】图的存储与出边的排序-CSDN博客
第二篇:
Dijkstra算法求解最短路径—— 从零开始的图论讲解(2) -CSDN博客
之前的博客中呢笔者给大家介绍了 图的概念,如何存图,如何简单遍历图,已经什么是图的拓扑排序
还介绍了Dijkstra算法,以及如何实现Dijkstra算法
按照之前的学习规划,本篇我们介绍另外一个求解最短路径问题的算法思想:Floyd算法
博客中出现的参考图都是笔者手画的,代码示例也是笔者手敲的!影响虽小,但请勿抄袭
Djikstra算法的缺陷
之前介绍Dijkstra 算法的时候,笔者就提到过,如果图的权值有负数,那么就无法使用Dijkstra算法去处理最短路径问题, 为什么呢?首先给大家看一个例子
请看如图,这是一个带了负权边的图:
假设节点1为源点,求到达各个点的最短路径,我们使用Dijkstra 算法,结果会是怎样?请看代码
import java.util.*;public class BetterperformanceDijkstra {static class Node{public int v;public int w;public Node(int v, int w) {this.v = v;this.w = w;}}static int n,m;static List<List<Node>> list = new ArrayList<>();public static void addEge(int u, int v, int w){list.get(u).add(new Node(v,w));}static boolean[] vis;static int[] dist;static final int INF = Integer.MAX_VALUE-20000000;
public static void dijkstra(int start)
{Arrays.fill(dist,INF);dist[start] = 0;PriorityQueue<Node> priorityQueue = new PriorityQueue<>(((o1, o2) -> o1.w-o2.w));Node cur = new Node(start,0);priorityQueue.offer(cur);while(!priorityQueue.isEmpty()){Node temp = priorityQueue.poll();int v = temp.v;int w = temp.w;if(vis[v]){continue;//已经访问过了}vis[v] = true;if(list.get(v)==null){continue;//没有联通的点}for(Node tep : list.get(v)){int vi = tep.v;int wi = tep.w;if(dist[vi]>dist[v]+wi)//维护最短路径{dist[vi] = dist[v]+wi;priorityQueue.offer(new Node(vi,dist[vi]));}}}
}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);n = scanner.nextInt();m = scanner.nextInt();for(int i=0;i<=n;i++){list.add(new ArrayList<>());}vis = new boolean[n+1];dist = new int[n+1];for(int i=0;i<m;i++){int a = scanner.nextInt();int b = scanner.nextInt();int c = scanner.nextInt();addEge(a,b,c);}dijkstra(1);for(int i = 1;i<=n;i++){System.out.print(dist[i]+" ");}}
}
结果如下:
可以看到,源点1到达节点4的最短路径长度为3 ,但是结果显示却是6
因此,在有些时候,使用Dijkstra 算法确实无法有效解决负权图的最短路径问题,那么这是为什么呢?
为什么无法解决负权图
首先让我们回顾一下Dijkstra算法的核心思想:
1.先选择好起点.
2.每次访问距离起点最近的,且之前没有被访问过的点
3.更新它的邻居的最短路径,并将其标记为已访问。
而Dijkstra 的算法核心原则就是
一旦某个节点
i
被选择,并且vis[i] = true
,那么我们无法通过节点 i 再次去更新到达其他点的权值了,哪怕有了更好的结果
这是一种贪心的思维策略,这个策略在所有边权都为非负数时是成立的,因为一旦确定某个节点的路径长度,后续不会出现比这个更短的路径。
但一旦图中含有负权边,这个“贪心假设”就会崩塌。
原因在于负权边会让后面的路径绕回来反而更短,但 Dijkstra 在更新某个节点后,不会再重新检查这个节点,导致了“错误答案”无法被修正。
读者可能会觉得上面的问题有点抽象,那么,就让我们结合这个样例,我们走一遍流程:
模拟流程
1.初始状态: 此时只有节点1进入了堆中
示意图: dist 数组表示 源点1到其他点的距离
PQ 代表堆中的元素
dist = [0, ∞, ∞, ∞]
PQ = { (1,0) }
2. 从
1
出发:
松弛操作:
dist[2] = 6
(从1→2
)松弛操作:
dist[3] = 5
(从1→3
)此时节点2,节点3都进入堆中
更新后的状态:
dist = [0, 6, 5, ∞]
PQ = { (3,5), (2,6) }
3. 弹出
3(5)
,标记vis[3] = true
,更新dist[4]
:
dist[4] = dist[3] + 1 = 5 + 1 = 6
(从3→4
)
更新后的状态:
dist = [0, 6, 5, 6]
PQ = { (2,6), (4,6) }
4: 弹出
2(6)
,标记vis[2] = true
,并进行尝试:
尝试
2→3
时,dist[3] = dist[2] + (-4) = 6 + (-4) = 2
,因为vis[3]
是true
,所以没有更新。 所以虽然dist[3] =6
, 但是,我们不会通过节点3去改变到达其他点的距离.
所以最后的结果为:
dist = [0, 6, 2, 6]
而我们希望的结果是:
dist = [0, 6, 2, 3]
通过上述的模拟演示,我们也能发现,在处理负权值图的最短路径时,Dijkstra 算法是有缺陷的
那么,我们可以选择 BF,SPFA,或者今天要介绍的Floyd 算法去解决,接下来,我们开始介绍Floyd算法
什么是Floyd算法
Floyd 算法,也称为Floyd-Warshall 算法。
Floyd 算法的最大特点就是简单直接,适用于任意权值(包括负权边,但不允许负权环),并且一次性可以算出任意两点之间的最短路径。
Floyd算法的核心思想
Floyd的思路可以归纳成一句话:
尝试用“中转点”去更新路径,看看能不能绕路更短!
假设我们有K个节点,此时 我们要从 节点 i 走到 节点 j,算法会尝试把图中每一个节点 k
都当作“中转站”:如果 i 到 k 的距离 + k 到 j 的距离 < i 到 j 当前的距离,那么就用这个更短的路径更新!
所以每次循环的本质就是在问:
“如果路上多绕一个第 k 个点,会不会比原来的路线还要短呢?”
通过这样不断地尝试,最终我们可以得到任意两点之间的最短路径。
看到这里,细心的同学也许会发现:这不就是一个经典的动态规划问题吗?
我们可以用一个三维数组来描述这个问题:
状态表示
dp[k][i][j] 表示:在只允许经过节点 1 ~ k 这些点的情况下,从 i 到 j 的最短路径长度。
状态转移方程
对应的状态转移方程为:
dp[k][i][j] = min(dp[k-1][i][j], dp[k-1][i][k] + dp[k-1][k][j])
什么意思呢?
假设你已经计算好了在“前 k-1 个点”的限制下,
从 i
到 j
的最短路径。
当第 k
个节点加入图中,路径有两种情况:
1️⃣ 不经过
k
,也就是:
还是用之前的路径dp[k-1][i][j]
即保持现状,和之前只有k-1个节点时一模一样
2️⃣ 经过
k
,路径变成:
dp[k-1][i][k] + dp[k-1][k][j]
将 i 到 j 的路径拆分成两段,先从 i 到 k,再从 k 到 j,看看这个组合的长度是否更短。
这里不涉及删除节点 i 或 j,只是用
k
当作中转点,把路径拆开看。
选择两者的最小值,更新当前的最短路径。
边界设置
那么,如何设置边界呢?
假设 i,j 有道路能直接相连,那么初始值 dp[0][i][j] 就是它们的 边长,否则,就应该赋值为无穷大
代码实现
public static void floyd() {for (int k = 1; k <= N; k++) { // 枚举中转点 kfor (int i = 1; i <= N; i++) { // 枚举起点 ifor (int j = 1; j <= N; j++) { // 枚举终点 jdp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);}}}
}***N表示总的节点数量***
逻辑解释
这段代码的核心含义是:
1. 最外层循环
k
:
依次尝试用每一个节点k
作为“中转点”。2. 中间层循环
i
:
从起点i
出发。3. 内层循环
j
:
目标是到达终点j
。在每次循环中,程序都在思考:
“如果从 i 到 j 的路径,经过中转点 k,是否能更短?”
如果能更短,就更新路径长度:
接下来我们附上完整的代码:
import java.util.Arrays;
import java.util.Scanner;public class Floyd {static long[][] dp;static long INF = Long.MAX_VALUE / 2; // 避免加法溢出static int N, M, Q;public static void floyd() {for (int k = 1; k <= N; k++) {for (int i = 1; i <= N; i++) {for (int j = 1; j <= N; j++) {dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);}}}}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);N = scanner.nextInt();M = scanner.nextInt();Q = scanner.nextInt();// 初始化 Floyd 数组dp = new long[N + 1][N + 1]; // N+1 是因为节点编号 1~Nfor (int i = 1; i <= N; i++) {Arrays.fill(dp[i], INF); // 逐行填充 INFdp[i][i] = 0; // 自己到自己距离为 0}// 读入 M 条边for (int i = 0; i < M; i++) {int u = scanner.nextInt();int v = scanner.nextInt();long w = scanner.nextLong();dp[u][v] = Math.min(dp[u][v], w); // 处理多重边,取最小值dp[v][u] = Math.min(dp[v][u], w); // 如果是无向图}// 执行 Floyd-Warshallfloyd();// 处理 Q 组查询for (int i = 0; i < Q; i++) {int st = scanner.nextInt();int ed = scanner.nextInt();if (dp[st][ed] == INF) {System.out.println(-1); // 不可达,输出 -1} else {System.out.println(dp[st][ed]);}}scanner.close();}
}
举例说明
还是用我们刚刚那个图来验证:
我们稍微修改一下示例代码,构成一个单向图,并且输出源点 1 到 其他点的举例
输入数据:
4 5
1 2 6
1 3 5
2 3 -4
3 4 1
2 4 100
import java.util.Arrays;
import java.util.Scanner;public class Floyd {static long[][] dp;static long INF = Long.MAX_VALUE / 2; // 避免加法溢出static int N, M, Q;public static void floyd() {for (int k = 1; k <= N; k++) {for (int i = 1; i <= N; i++) {for (int j = 1; j <= N; j++) {dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j]);}}}}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);N = scanner.nextInt();M = scanner.nextInt();
// Q = scanner.nextInt();// 初始化 Floyd 数组dp = new long[N + 1][N + 1]; // ✅ N+1 是因为节点编号 1~Nfor (int i = 1; i <= N; i++) {Arrays.fill(dp[i], INF); // ✅ 逐行填充 INFdp[i][i] = 0; // ✅ 自己到自己距离为 0}// 读入 M 条边for (int i = 0; i < M; i++) {int u = scanner.nextInt();int v = scanner.nextInt();long w = scanner.nextLong();dp[u][v] = Math.min(dp[u][v], w); // ✅ 处理多重边,取最小值}// 执行 Floyd-Warshallfloyd();for(int i = 1;i<=N;i++){System.out.print(dp[1][i]+" ");}
// // 处理 Q 组查询
// for (int i = 0; i < Q; i++) {
// int st = scanner.nextInt();
// int ed = scanner.nextInt();
// if (dp[st][ed] == INF) {
// System.out.println(-1); // 不可达,输出 -1
// } else {
// System.out.println(dp[st][ed]);
// }
// }scanner.close();}
}
读者们复制进去后,能发现,结果为:
验证成功,使用 Floyd算法能解决该问题
Floyd算法的特点
支持负权边(前提:没有负权环)
不像 Dijkstra 那样只解决“单源”最短路径,可以一网打尽,计算任意两点之间的最短距离
通过一次Floyd 算法,我们可以得到图中任意两点的距离,没错,是随便两个点的距离!!!
算法结构简单,写起来很容易
适用于稠密图(边很多的图)
时间复杂度有一点高,是 O(n^3),当节点数不大时非常方便好用,最好控制在300以内
结尾
博客的内容就暂时写到这里,系列下篇更新 BF算法和SPFA算法,
相关文章:
Floyd算法求解最短路径问题——从零开始的图论讲解(3)
目录 前言 Djikstra算法的缺陷 为什么无法解决负权图 模拟流程 什么是Floyd算法 Floyd算法的核心思想 状态表示 状态转移方程 边界设置 代码实现 逻辑解释 举例说明 Floyd算法的特点 结尾 前言 这是笔者图论系列的第三篇博客 第一篇: 图的概念,图的存储,图的…...
spark和hadoop的区别与联系
区别 1. 数据处理模型 Hadoop:主要依赖 MapReduce 模型,计算分 Map(映射)和 Reduce(归约)两个阶段,中间结果常需写入磁盘,磁盘 I/O 操作频繁,数据处理速度相对受限&#…...
XMLXXE 安全无回显方案OOB 盲注DTD 外部实体黑白盒挖掘
# 详细点: XML 被设计为传输和存储数据, XML 文档结构包括 XML 声明、 DTD 文档类型定义(可 选)、文档元素,其焦点是数据的内容,其把数据从 HTML 分离,是独立于软件和硬件的 信息传输…...
C# .NET如何自动实现依赖注入(DI)
为解决重复性的工作,自动实现依赖注入(DI) 示例代码如下 namespace DialysisSOPSystem.Infrastructure {public static class ServiceCollectionExtensions{/// <summary>/// 批量注入服务/// </summary>/// <param name&qu…...
FastGPT Docker Compose本地部署与硅基流动免费AI接口集成指南
本文参考:https://doc.tryfastgpt.ai/docs/development/ 一、背景与技术优势 FastGPT是基于LLM的知识库问答系统,支持自定义数据训练与多模型接入。硅基流动(SiliconFlow)作为AI基础设施平台,提供高性能大模型推理引…...
AI对话高效输入指令攻略(三):使用大忌——“AI味”
免责声明: 1.本文所提供的所有 AI 使用示例及提示词,仅用于学术写作技巧交流与 AI 功能探索测试,无任何唆使或鼓励利用 AI 抄袭作业、学术造假的意图。 2.文章中提及的内容旨在帮助读者提升与 AI 交互的能力,合理运用 AI 辅助学…...
算法 | 成长优化算法(Growth Optimizer,GO)原理,公式,应用,算法改进研究综述,matlab代码
===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 成长优化算法 一、算法原理二、核心公式三、应用领域四、算法改进研究五…...
生产环境问题排查:日志分析与性能瓶颈定位(一)
引言 在当今数字化时代,各类应用系统如潮水般涌现,支撑着我们生活和工作的方方面面。从日常使用的电商平台、社交网络,到企业内部复杂的业务系统,它们的稳定运行和高效性能至关重要。而在生产环境中,日志分析与性能瓶…...
go语言的八股文
1.go语言触发异常的场景有哪些 运行时错误 1.空指针解引用:尝试访问一个未初始化的指针指向的内存,会导致程序崩溃并触发异常。 2.数组越界访问:试图访问数组中不存在的索引,比如数组长度为5,却尝试访问索引为10的元素…...
Office文件内容提取 | 获取Word文件内容 |Javascript提取PDF文字内容 |PPT文档文字内容提取
关于Office系列文件文字内容的提取 本文主要通过接口的方式获取Office文件和PDF、OFD文件的文字内容。适用于需要获取Word、OFD、PDF、PPT等文件内容的提取实现。例如在线文字统计以及论文文字内容的提取。 一、提取Word及WPS文档的文字内容。 支持以下文件格式: …...
组态软件工业化自动领域的可视化配置利器
组态软件是工业自动化领域的可视化配置利器,在工业生产中发挥着至关重要的作用,以下从定义、特点、功能、应用场景、市场现状及发展趋势等方面进行详细介绍: 定义 组态软件,又称组态监控系统软件,是用于数据采集和过程…...
Ansys electronics安装多版本simulink打开s-function冲突解决方法
安装了Ansys Electronics 2022 R1和2024 R1,想通过simplorer和simulink中的S-function进行联合仿真,结果注册表一直是2024 R1,修改方法如下: 1. WINR打开cmd,注意要用管理员权限打开 2. 输入 "D:\ANSYS\AnsysE…...
ubuntu--安装双系统
教程 BIOS设置 启动盘生成和ubuntu安装 boot option #1设置USB为第一启动项 rufus下载 官网: 链接 点击“链接”下面的按钮,即可下载。(注意查看自己的电脑是x64还是x84) 网盘下载: 链接...
快速搭建 Cpolar 内网穿透(Mac 系统)
1、Cpolar快速入门教程(官方) 链接地址:Cpolar 快速入门 2、官方教程详解 本地安装homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"这个是从 git 上拉取的&#x…...
【pytorch】torch.nn.Unfold操作
说明 一个代码里涉及到了unfold的操作,看了半天官网都没整明白维度怎么变化的,参考这个链接搞明白了: https://blog.csdn.net/ViatorSun/article/details/119940759 https://zhuanlan.zhihu.com/p/361140988 维度计算 输入( N,…...
使用PyTorch实现图像增广与模型训练实战
本文通过完整代码示例演示如何利用PyTorch和torchvision实现常用图像增广方法,并在CIFAR-10数据集上训练ResNet-18模型。我们将从基础图像变换到复杂数据增强策略逐步讲解,最终实现一个完整的训练流程。 一、图像增广基础操作 1.1 准备工作 #matplotli…...
PyTorch实现糖尿病预测的CNN模型:从数据加载到模型部署全解析【N折交叉验证、文末免费下载】
本文将详细介绍如何使用PyTorch框架构建一个卷积神经网络(CNN)来预测糖尿病,包含完整的代码实现、技术细节和可视化分析。 1. 项目概述 本项目使用经典的Pima Indians Diabetes数据集,通过5折交叉验证训练一个1D CNN模型,最终实现糖尿病预测…...
红队专题-漏洞挖掘-代码审计-反序列化
漏洞挖掘-代码审计-反序列化 加固/防御命令执行相关日志Tools-JNDIExploitJNDI Java Naming and Directory Interface Java命名目录接口注入原理payload参数渗透测试-php命令执行-RCE+Struts2拿webshell普通权限 命令执行 拿 webshellCMD echo 写入一句话 php文件菜刀连接Strut…...
【2025软考高级架构师】——计算机系统基础(7)
摘要 本文主要介绍了计算机系统的组成,包括硬件和软件两大部分。硬件由处理器、存储器、总线、接口和外部设备等组成,软件则涵盖系统软件和应用软件。文章还详细阐述了冯诺依曼计算机的组成结构,包括 CPU、主存储器、外存等,并解…...
【网络原理】TCP协议如何实现可靠传输(确认应答和超时重传机制)
目录 一. TCP协议 二. 确定应答 三. 超时重传 一. TCP协议 1)端口号 源端口号:发送方端口号目的端口号:接收方端口号 16位(2字节)端口号,可以表示的范围(0~65535) 源端口和目的…...
Java synchroinzed和ReentrantLock
synchronized —— JVM亲儿子的暗黑兵法 核心思想:“锁即对象,对象即锁!” 底层三板斧 对象头里的锁密码 每个Java对象头里藏了两个骚东西: Mark Word:32/64位的比特修罗场,存哈希码、GC年龄࿰…...
【Linux】vim配置----超详细
目录 一、插件管理器准备 二、目录准备 三、安装插件 一、插件管理器准备 Vim-plug 是一个Vim插件管理器,利用异步并行可以快速地安装、更新和卸载插件。它的安装和配置都非常简单,而且在操作过程中会给出很多易读的反馈信息,是一个自由、…...
驱动开发硬核特训 · Day 15:电源管理核心知识与实战解析
在嵌入式系统中,电源管理(Power Management)并不是“可选项”,而是实际部署中影响系统稳定性、功耗、安全性的重要一环。今天我们将以 Linux 电源管理框架 为基础,从理论结构、内核架构,再到典型驱动实战&a…...
如何使用人工智能大模型,免费快速写工作计划?
如何使用人工智能大模型,免费快速写工作计划? 具体视频教程https://edu.csdn.net/learn/40406/666579...
延长(暂停)Windows更新
延长(暂停)Windows更新 因为不关闭更新有时候就会出现驱动或者软硬件不兼容,导致蓝屏出现。 注:为什么选择延长更新而不是用软件暂停更新,因为使用软件暂停更新会出现一下问题,比如微软商店打不开等等 键…...
QT实现串口透传的功能
在一些产品的开发的时候,需要将一个串口的数据发送给另外一个串口进行转发。 具体的代码如下: #include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::Ma…...
分布类相关的可视化图像
目录 一、直方图(Histogram) 1.定义 2.特点 3.局限性 4.类型 5.应用场景 6.使用Python实现 二、密度图(Density Plot) 1.定义 2.特点 3.局限性 4.类型 5.应用场景 6.使用Python实现 三、箱线图(Box Plo…...
【android bluetooth 框架分析 02】【Module详解 12】【 BidiQueue、BidiQueueEnd、Queue介绍】
1. BidiQueue 和 BidiQueueEnd 蓝牙协议栈里面有很多 BidiQueue ,本节就专门来梳理这块内容。 2. BidiQueue 介绍 BidiQueue,是 Host 与 Controller 层通信的中枢之一, acl_queue_、sco_queue_、iso_queue_ 都是 BidiQueue 类型。让我们一起看一下这个…...
c++通讯录管理系统
通讯录是一个可以记录亲人,好友的信息工具。 功能包括: 1,添加联系人:向通讯录添加新人,包括(姓名,性别年龄,联系电话,家庭住址) 2,显示联系人…...
React 打包
路由懒加载 原本的加载方式 #使用lazy()函数声明的路由页面 使用Suspense组件进行加载 使用CDN优化...
day1 python训练营
变量与输出 print(1,2,3,sep\n,endsep用来区分两个变量,end会紧跟最后一个变量) print(1,2,3,sepaaa,endsep用来区分两个变量,3后面不会再输出aaa) 格式化字符串 变量名值 print(f"变量名{变量名}") 变量的基础运算 ,-*,/ 注意*不要忘写。比如2j就不…...
C语言状态字与库函数详解:概念辨析与应用实践
C语言状态字与库函数详解:概念辨析与应用实践 一、状态字与库函数的核心概念区分 在C语言系统编程中,"状态字"和"库函数"是两个经常被混淆但本质完全不同的概念,理解它们的区别是掌握系统编程的基础。 1. 状态字&…...
软件测试笔记(测试的概念、测试和开发模型介绍、BUG介绍)
软件测试笔记 认识测试 软件测试是啥? 说白了,就是检查软件的功能和效果是不是用户真正想要的东西。比如用户说“我要一个能自动算账的软件”,测试就是看这个软件到底能不能准确算账、有没有漏掉功能。 软件测试定义:软件测试就…...
Python多进程同步全解析:从竞争条件到锁、信号量的实战应用
1. 进程同步的必要性 在多进程编程中,当多个进程需要访问共享资源时,会出现竞争条件问题。例如火车票售卖系统中,如果多个售票窗口同时读取和修改剩余票数,可能导致数据不一致。 1.1 竞争条件示例 from multiprocessing import…...
Vue3 + TypeScript,关于item[key]的报错处理方法
处理方法1:// ts-ignore 注释忽略报错 处理方法2:item 设置为 any 类型...
Spring源码中关于抽象方法且是个空实现这样设计的思考
Spring源码抽象方法且空实现设计思想 在Spring源码中onRefresh()就是一个抽象方法且空实现,而refreshBeanFactory()方法就是一个抽象方法。 那么Spring源码中onRefresh方法定义了一个抽象方法且是个空实现,为什么这样设置,好处是什么。为…...
Pandas数据可视化
在当今这个数据驱动的时代,数据可视化已经成为数据分析不可或缺的一部分。通过图形化的方式展示数据,我们能够更直观地理解数据的分布、趋势和关系,从而做出更加精准的决策。Pandas,作为Python中最为流行的数据处理库,…...
string类(详解)
【本节目标】 1. 为什么要学习string类 2. 标准库中的string类 3. string类的模拟实现 4. 扩展阅读 1. 为什么学习string类? 1.1 C语言中的字符串 C 语言中,字符串是以 \0 结尾的一些字符的集合,为了操作方便, C 标准库中提供…...
零基础上手Python数据分析 (19):Matplotlib 高级图表定制 - 精雕细琢,让你的图表脱颖而出!
写在前面 —— 超越默认样式,掌握 Matplotlib 精细控制,打造专业级可视化图表 上一篇博客,我们学习了 Matplotlib 的基础绘图功能,掌握了如何绘制常见的折线图、柱状图、散点图和饼图,并进行了基本的图表元素定制,例如添加标题、标签、图例等。 这些基础技能已经能让我…...
【上位机——MFC】MFC入门
MFC库中相关类简介 CObject MFC类库中绝大部分类的父类,提供了MFC类库中一些基本的机制。 对运行时类信息的支持。对动态创建的支持。对序列化的支持。 CWinApp 应用程序类,封装了应用程序、线程等信息。 CDocument 文档类,管理数据 F…...
ASP.NET Core 最小 API:极简开发,高效构建(下)
在上篇文章 ASP.NET Core 最小 API:极简开发,高效构建(上) 中我们添加了 API 代码并且测试,本篇继续补充相关内容。 一、使用 MapGroup API 示例应用代码每次设置终结点时都会重复 todoitems URL 前缀。 API 通常具有…...
【leetcode100】一和零
1、题目描述 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。 示例 1: 输入:…...
代码随想录算法训练营第五十三天 | 105.有向图的完全可达性 106.岛屿的周长
105.有向图的完全可达性 题目链接:101. 孤岛的总面积 文章讲解:代码随想录 视频讲解:图论:岛屿问题再出新花样 | 深搜优先搜索 | 卡码网:101.孤岛总面积_哔哩哔哩_bilibili 思路: 1.确认递归函数&…...
在 Debian 10.x 安装和配置 Samba
1. 更新系统 sudo apt update sudo apt upgrade -y2. 安装 Samba sudo apt install samba -y3. 配置 Samba 备份默认配置文件 sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak编辑配置文件 sudo nano /etc/samba/smb.conf示例配置(共享目录) …...
Python中的短路运算
近期在学习python的过程中遇到此问题,遂总结记录 在”and“逻辑判定布尔类型时: 若判定对象均为True,则输出最后一个判别为True的对象 若判定对象的数据类型中有布尔类型,且最终结果为False,则输出布尔类型False 若判定对象的…...
Java8-遍历list取出两个字段重新组成list集合
在Java 8中,可以使用Stream API遍历List并提取两个字段重新组合成新的List。 以下是几种常见方法: 方法1:使用自定义类 定义一个包含目标字段的类:public class FieldHolder {private final String field1;private final int field2;public FieldHolder(String field1, i…...
【C++ 程序设计】实战:C++ 实践练习题(31~40)
目录 31. 数列:s 1 + 2 + 3 + … + n 32. 数列:s 1 - 2 - 3 - … - n 33. 数列:s 1 + 2 - 3 + … - n 34. 数列:s 1 - 2 + 3 - … &#…...
【笔记】SpringBoot实现图片上传和获取图片接口
上传图片接口 接口接收图片文件和布尔类型的是否生成缩略图参数。 生成保存图片文件的文件夹,文件夹的命名为上传图片的日期“根目录\file\cover\202504”,如果文件夹已存在则不生成。接下来拼接文件名,生成30位的随机数拼接到原文件名防止文件名相同的…...
Linux 下依赖库的问题
假设你在 某用户 user_name 下安装了一个 rquests库。 然后你在命令行使用 python3 -c (...)验证。发现没有任何问题。 然后你使用python3 xxx.py 发现执行验证也没有问题。 这个时候你信心慢慢的写了一个C的代码在代码中system调用这个.py文件。 然…...
STM32 HAL 水位传感器驱动程序
工作原理是输出模拟量电压值,只需要使用stm32adc读取电压再转换一下即可 本代码中,水位传感器连接在PA0,可通过宏定义快速设置电压区间和水位之间的关系 water_level.c /***************************************************************…...