当前位置: 首页 > news >正文

图论(二)之最短路问题

最短路

Dijkstra求最短路

文章目录

  • 最短路
    • Dijkstra求最短路
      • 栗题
      • 思想
      • 题目
      • 代码
      • 代码如下
      • bellman-ford
      • 算法分析
      • 只能用bellman-ford来解决的题型
      • 题目
      • 完整代码
    • spfa求最短路
      • spfa 算法思路
        • 明确一下松弛的概念。
        • spfa算法文字说明:
        • spfa 图解:
      • 题目
      • 完整代码
      • 总结tips
    • spfa判断负环
      • 算法分析
      • 代码如下
      • Floyd求最短路
      • 模拟过程
          • 链接:[https://www.acwing.com/problem/content/856/](https://www.acwing.com/problem/content/856/)
      • 题目
      • 代码如下

栗题

https://www.acwing.com/problem/content/851/

https://www.acwing.com/problem/content/852/

思想

迪杰斯特拉算法采用的是一种贪心的策略。

求源点到其余各点的最短距离步骤如下:

  1. 用一个 dist 数组保存源点到其余各个节点的距离,dist[i] 表示源点到节点 i 的距离。初始时,dist 数组的各个元素为无穷大。
    用一个状态数组 state 记录是否找到了源点到该节点的最短距离,state[i] 如果为真,则表示找到了源点到节点 i 的最短距离,state[i] 如果为假,则表示源点到节点 i 的最短距离还没有找到。初始时,state 各个元素为假。

03.png

  1. 源点到源点的距离为 0。即dist[1] = 0。

04.png

  1. 遍历 dist 数组,找到一个节点,这个节点是:没有确定最短路径的节点中距离源点最近的点。假设该节点编号为 i。此时就找到了源点到该节点的最短距离,state[i] 置为 1。

    05.png

  2. 遍历 i 所有可以到达的节点 j,如果 dist[j] 大于 dist[i] 加上 i -> j 的距离,即 dist[j] > dist[i] + w[i][j](w[i][j] 为 i -> j 的距离) ,则更新 dist[j] = dist[i] + w[i][j]。

    06.png

  3. 重复 3 4 步骤,直到所有节点的状态都被置为 1。

    071.png

  4. 此时 dist 数组中,就保存了源点到其余各个节点的最短距离。

    13.png

题目

在这里插入图片描述

代码

#include<iostream>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 510, M = 100010;int h[N], e[M], ne[M], w[M], idx;//邻接表存储图
int state[N];//state 记录是否找到了源点到该节点的最短距离
int dist[N];//dist 数组保存源点到其余各个节点的距离
int n, m;//图的节点个数和边数void add(int a, int b, int c)//插入边
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}void Dijkstra()
{memset(dist, 0x3f, sizeof(dist));//dist 数组的各个元素为无穷大dist[1] = 0;//源点到源点的距离为置为 0for (int i = 0; i < n; i++){int t = -1;for (int j = 1; j <= n; j++)//遍历 dist 数组,找到没有确定最短路径的节点中距离源点最近的点t{if (!state[j] && (t == -1 || dist[j] < dist[t]))t = j;}state[t] = 1;//state[i] 置为 1。for (int j = h[t]; j != -1; j = ne[j])//遍历 t 所有可以到达的节点 i{int i = e[j];dist[i] = min(dist[i], dist[t] + w[j]);//更新 dist[j]}}
}int main()
{memset(h, -1, sizeof(h));//邻接表初始化cin >> n >> m;while (m--)//读入 m 条边{int a, b, w;cin >> a >> b >> w;add(a, b, w);}Dijkstra();if (dist[n] != 0x3f3f3f3f)//如果dist[n]被更新了,则存在路径cout << dist[n];elsecout << "-1";
}

优化

下面进行优化,可以看出上方时间复杂度为 O ( n 2 ) O(n^2) O(n2), 查找距离源点最近的点没有被确定的点t需要 O ( n ) O(n) O(n),遍历t所有可以到达的节点 i需要 O ( n ) O(n) O(n), 而这可以进行优化

  • 若是用小根堆(优先队列)进行存储, 那么每次找距离最近的那个点t只需要 O ( 1 ) O(1) O(1),而遍历t所有可以到达的需要 O ( m l o g n ) O(mlog_n) O(mlogn)因为堆的修改需要 O ( l o g n ) O(log_n) O(logn)

代码如下

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 150010;
//用邻接表的话重边可以不用考虑
typedef pair<int, int> PII;
int h[N], w[N], ne[N], idx, e[N];
int n, m;
bool st[N];
int dist[N];
void add(int a, int b, int c) {e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}int dijkstra() {memset(dist, 0x3f3f3f3f, sizeof dist);dist[1] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1});  //{距离,编号}while(heap.size()) {auto t = heap.top();heap.pop();int no = t.second, distance = t.first;if(st[no])  continue;   //若此编号已经找到距离,那么跳过st[no] = true;for(int i = h[no]; i != -1; i = ne[i]) {int j = e[i];if(dist[j] > dist[no] + w[i]) {dist[j] = dist[no] + w[i];heap.push({dist[j], j});}}}if(dist[n] == 0x3f3f3f3f)   return -1;return dist[n];
}int main() {scanf("%d%d", &n, &m);//邻接表第一步的必备memset(h, -1, sizeof h);while(m --) {int a, b, c;scanf("%d%d%d", &a, &b, &c);add(a, b, c);}int t = dijkstra();cout << t;return 0;
}

bellman-ford

算法分析

1、问题:为什么Dijkstra不能使用在含负权的图中?
(这是以前错误的分析,若看完这个例子分析觉得正确的说明对最短路理解得还不够透彻,这里不做删除)
分析:如图所示:
若通过Dijkstra算法可以求出从1号点到达4号点所需的步数为3 (每次选择离源点最短距离的点更新其他点)
但实际上从 1 号点到达 4 号点所需步数为 1 (1 –> 2 –> 3),因此不能使用 Dijkstra 解决含负权图的问题

200fb33caef2d3ce435369aaa777f83.png

正确的分析
Dijkstra算法的3个步骤

1、找到当前未标识的且离源点最近的点t
2、对t号点点进行标识
3、用t号点更新其他点的距离
反例

8886031fd08869a6757d4c704c6f355.png

结果:

dijkstra算法在图中走出来的最短路径是1 -> 2 -> 4 -> 5,算出 1 号点到 5 号点的最短距离是2 + 2 + 1 = 5,然而还存在一条路径是1 -> 3 -> 4 -> 5,该路径的长度是5 + (-2) + 1 = 4,因此 dijkstra 算法失效

dijkstra详细步骤

  • 初始dist[1] = 0`

  • 找到了未标识且离源点1最近的结点1,标记1号点,用1号点更新其他所有点的距离,2号点被更新成dist[2] = 2,3号点被更新成

    dist[3] = 5

  • 找到了未标识且离源点1最近的结点2,标识2号点,用2号点更新其他所有点的距离,4号点被更新成dist[4] = 4

  • 找到了未标识且离源点1最近的结点4,标识4号点,用4号点更新其他所有点的距离,5号点被更新成dist[5] = 5

  • 找到了未标识且离源点1最近的结点3,标识3号点,用3号点更新其他所有点的距离,4号点被更新成dist[4] = 3
    结束

  • 得到1号点到5号点的最短距离是5,对应的路径是1 -> 2 -> 4 -> 5,并不是真正的最短距离

2、什么是bellman - ford算法?
Bellman - ford 算法是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小。其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在 n-1 次松弛后还能更新,则说明图中有负环,因此无法得出结果,否则就完成。
(通俗的来讲就是:假设 1 号点到 n 号点是可达的,每一个点同时向指向的方向出发,更新相邻的点的最短距离,通过循环 n-1 次操作,若图中不存在负环,则 1 号点一定会到达 n 号点,若图中存在负环,则在 n-1 次松弛后一定还会更新)

3、bellman - ford算法的具体步骤

for n次for 所有边 a,b,w (松弛操作)dist[b] = min(dist[b],back[a] + w)

注意:back[] 数组是上一次迭代后 dist[] 数组的备份,由于是每个点同时向外出发,因此需要对 dist[] 数组进行备份,若不进行备份会因此发生串联效应,影响到下一个点

为什么需要back[a]数组
为了避免如下的串联情况, 在边数限制为一条的情况下,节点3的距离应该是3,但是由于串联情况,利用本轮更新的节点2更新了节点3的距离,所以现在节点3的距离是2。

2.PNG

正确做法是用上轮节点2更新的距离–无穷大,来更新节点3, 再取最小值,所以节点3离起点的距离是3。

3.PNG

for (int i = 0; i < k; i ++ )
{memcpy(backup, dist, sizeof dist);for (int j = 0; j < m ; j ++ ){int a = edges[j].a, b = edges[j].b, w = edges[j].w;dist[b] = min(dist[b], backup[a] + w);}
}

4、在下面代码中,是否能到达n号点的判断中需要进行if(dist[n] > INF/2)判断,而并非是if(dist[n] == INF)判断,原因是INF是一个确定的值,并非真正的无穷大,会随着其他数值而受到影响,dist[n]大于某个与INF相同数量级的数即可

5、bellman - ford算法擅长解决有边数限制的最短路问题
时间复杂度 O(nm)

其中n为点数,m为边数

作者:小呆呆
链接:https://www.acwing.com/solution/content/6320/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

只能用bellman-ford来解决的题型

有边数限制的最短路

这里题目说了可能为负权边或者负权回路,那么就不能用dijkstraspfa算法

dijkstra不能解决负权边是因为 dijkstra要求每个点被确定后st[j] = true,dist[j]就是最短距离了,之后就不能再被更新了(一锤子买卖),而如果有负权边的话,那已经确定的点的dist[j]不一定是最短了

题目

在这里插入图片描述

完整代码

```cpp
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 510, M = 10010;struct Edge
{int a, b, c;
}edges[M];int n, m, k;
int dist[N];
int last[N];void bellman_ford()
{memset(dist, 0x3f, sizeof dist);dist[1] = 0;for (int i = 0; i < k; i ++ ){memcpy(last, dist, sizeof dist);for (int j = 0; j < m; j ++ ){auto e = edges[j];dist[e.b] = min(dist[e.b], last[e.a] + e.c);}}
}int main()
{scanf("%d%d%d", &n, &m, &k);for (int i = 0; i < m; i ++ ){int a, b, c;scanf("%d%d%d", &a, &b, &c);edges[i] = {a, b, c};}bellman_ford();if (dist[n] > 0x3f3f3f3f / 2) puts("impossible");else printf("%d\n", dist[n]);return 0;
}```

spfa求最短路

spfa 算法思路

明确一下松弛的概念。
  • 考虑节点u以及它的邻居v,从起点跑到v有好多跑法,有的跑法经过u,有的不经过。

  • 经过u的跑法的距离就是dist[u]+u到v的距离。

  • 所谓松弛操作,就是看一看dist[v]和dist[u]+u到v的距离哪个大一点。

  • 如果前者大一点,就说明当前的不是最短路,就要赋值为后者,这就叫做松弛。

spfa算法文字说明:
  • 一个队列,初始时队列里只有起始点。

  • 再建立一个数组记录起始点到所有点的最短路径(该表格的初始值要赋为极大值,该点到他本身的路径赋为0)。

  • 再建立一个数组,标记点是否在队列中。

  • 队头不断出队,计算始点起点经过队头到其他点的距离是否变短,如果变短且被点不在队列中,则把该点加入到队尾。

  • 重复执行直到队列为空。

  • 在保存最短路径的数组中,就得到了最短路径。

spfa 图解:
  • 给定一个有向图,如下,求A~E的最短路。

1.png

  • 源点A首先入队,然后A出队,计算出到BC的距离会变短,更新距离数组,BC没在队列中,BC入队

2.png

  • B出队,计算出到D的距离变短,更新距离数组,D没在队列中,D入队。然后C出队,无点可更新。

3.png

  • D出队,计算出到E的距离变短,更新距离数组,E没在队列中,E入队。

  • 4.png

  • E出队,此时队列为空,源点到所有点的最短路已被找到,A->E的最短路即为8

    5.png

题目

https://www.acwing.com/problem/content/853/

在这里插入图片描述

完整代码

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 100010;
int w[N], h[N], idx, ne[N], e[N];
int n, m;
int dist[N];    //各点到源点的距离
bool st[N];
void add(int a, int b, int c) {e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}int spfa() {memset(dist, 0x3f3f3f3f, sizeof dist);dist[1] = 0;queue<int> q;    q.push(1);st[1] = true;   //代表在队列中了while(q.size()) {auto t = q.front();q.pop();st[t] = false;for(int i = h[t]; i != -1; i = ne[i]) {int j = e[i];if(dist[j] > dist[t] + w[i]) {dist[j] = dist[t] + w[i];if(!st[j]) {q.push(j);st[j] = true;   //在队列中了}}}}return dist[n];
}int main() {memset(h, -1, sizeof h);cin >> n >> m;while(m --) {int a, b, w;scanf("%d%d%d", &a, &b, &w);add(a, b, w);}int res = spfa();if(res == 0x3f3f3f3f)   cout << "impossible";else cout << res;return 0;
}

总结tips

在这里插入图片描述


spfa判断负环

https://www.acwing.com/problem/content/854/

算法分析

使用spfa算法解决是否存在负环问题

求负环的常用方法,基于SPFA,一般都用方法 2(该题也是用方法 2):

  • 方法 1:统计每个点入队的次数,如果某个点入队n次,则说明存在负环-
  • 方法 2:统计当前每个点的最短路中所包含的边数,如果某点的最短路所包含的边数大于等于n,则也说明存在环
  1. dist[x] 记录虚拟源点到x的最短距离

  2. cnt[x] 记录当前x点到虚拟源点最短路的边数,初始每个点到虚拟源点的距离为0,只要他能再走n步,即cnt[x] >= n,则表示该图中一定存在负环,由于从虚拟源点到x至少经过n条边时,则说明图中至少有n + 1个点,表示一定有点是重复使用

  3. dist[j] > dist[t] + w[i],则表示从t点走到j点能够让权值变少,因此进行对该点j进行更新,并且对应cnt[j] = cnt[t] + 1,往前走一步

注意:该题是判断是否存在负环,并非判断是否存在从1开始的负环,因此需要将所有的点都加入队列中,更新周围的点

故只需要对上方代码稍做改动即可:

代码如下

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 100010;
int w[N], h[N], idx, ne[N], e[N];
int n, m;
int dist[N];    //各点到源点的距离
int cnt[N]; //存储边的个数
bool st[N];
void add(int a, int b, int c) {e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}int spfa() {memset(dist, 0x3f3f3f3f, sizeof dist);	dist[1] = 0;			queue<int> q;    for(int i = 1; i <= n; i++) {st[i] = true;q.push(i);}while(q.size()) {auto t = q.front();q.pop();st[t] = false;for(int i = h[t]; i != -1; i = ne[i]) {int j = e[i];if(dist[j] > dist[t] + w[i]) {dist[j] = dist[t] + w[i];cnt[j] = cnt[t] + 1;if(cnt[j] > n)  return true;if(!st[j]) {q.push(j);st[j] = true;   //在队列中了}}}}return false;
}int main() {memset(h, -1, sizeof h);cin >> n >> m;while(m --) {int a, b, w;scanf("%d%d%d", &a, &b, &w);add(a, b, w);}bool res = spfa();if(res) cout << "Yes";else cout << "No";return 0;
}

Floyd求最短路

求多源最短路

通过中转动态规划来递推出最短路径距离

ij经过k,通过三重循环来实现

初始化自环为0,其他为INF

对于重边的情况下,我们初始化取最小距离

模拟过程

在这里插入图片描述

在这里插入图片描述

链接:https://www.acwing.com/problem/content/856/

题目

在这里插入图片描述

代码如下

using namespace std;
const int N = 210, INF = 1e9;
int n, m, Q;
int d[N][N];
void floyd() {for(int k = 1; k <= n; k++)		//依次经过1~n中的n各点进行中转for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
int main() {cin >> n >> m >> Q;//初始化处理重边和自环for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)if(i == j)  d[i][j] = 0;else d[i][j] = INF;while(m --) {int x, y, z;scanf("%d%d%d", &x, &y, &z);d[x][y] = min(d[x][y], z);}floyd();while(Q --) {int a, b;scanf("%d%d", &a, &b);int res = d[a][b];if(res > INF / 2) printf("impossible\n");else cout << res << '\n';}return 0;
}

相关文章:

图论(二)之最短路问题

最短路 Dijkstra求最短路 文章目录 最短路Dijkstra求最短路栗题思想题目代码代码如下bellman-ford算法分析只能用bellman-ford来解决的题型题目完整代码 spfa求最短路spfa 算法思路明确一下松弛的概念。spfa算法文字说明&#xff1a;spfa 图解&#xff1a; 题目完整代码总结ti…...

.NET Core 日志记录功能详解

在软件开发和运维过程中&#xff0c;日志记录是一个非常重要的功能。它可以帮助开发者跟踪应用程序的运行状况、诊断和监控问题。.NET Core 提供了一个灵活且易于使用的日志系统&#xff0c;本文将详细介绍.NET Core日志的相关概念、配置和使用方法。 1. 什么是日志记录以及它…...

docker——启动各种服务

1.Mysql 2.Redis 3.nginx 4.ES 注意&#xff1a;ES7之后环境为 -e ELASTICSEARCH_HOSTS http://ip地址:9200...

git远程仓库使用

赋值这个地址clone 克隆之后 cd slam_oncloud/ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/slam_oncloud.git 查看一下 linuxchenxiao:/media/linux/mydisk/cloud_slam/slam_oncloud$ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/sla…...

js导出的excel文件无法打开/打开乱码,excel无法打开xxx.xlsx因为文件格式或文件扩展无效

excel无法打开xxx.xlsx因为文件格式或文件扩展无效 使用 a 标签导出这里就不细说了&#xff0c;直接说上述问题解决方案 在调用导出接口的时候加上两个参数 responseType: “blob” responseEncoding: “utf8” export function test(data) {return util({url: /test,method: …...

透明多级分流系统(用户端缓存和负载均衡)

部件考虑 有些设备位于客户端或者网络边缘&#xff0c;能够迅速响应用户请求&#xff0c;避免给cpu和数据库带来压力&#xff0c;比如&#xff0c;本地缓存&#xff0c;内容分发网络&#xff0c;反向代理等。 有些设备处理能力能够线性扩展&#xff0c;易于伸缩&#xff0c;应…...

Python sort从大到小排序面试题

在Python中&#xff0c;你可以使用内置的sorted()函数或者列表的sort()方法来对列表中的元素进行从大到小的排序。 使用sorted()函数&#xff1a; numbers [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] sorted_numbers sorted(numbers, reverseTrue) # 设置reverseTrue实现从大到小排…...

【Stable Diffusion】入门:AI绘画提示词+参数设置攻略

目录 1 提示词1.1 分类和书写方式1.1.1 内容型提示词1.1.2 标准化提示词1.1.3 通用模板 1.2 权重1.2.1 套括号1.2.2 数字权重1.2.3 进阶语法 1.3 负面提示词 2 参数详解2.1 Sampling steps2.2 Sampling method2.3 Width, Height2.4 CFG Scale2.5 Seed2.6 Batch count, Batch si…...

Qt使用Q_DECLARE_INTERFACE Q_INTERFACES宏实现接口类使用qobject_cast进行类型转换

在写抽象类或者接口的时候&#xff0c;肯定是不能继承QObject的 但是又想使用qobject_cast进行类型转换&#xff0c;使用以下办法就能实现 #ifndef FACTORYINTERFACE_H__ #define FACTORYINTERFACE_H__ #include <QObject> class FactoryInterface{ public:FactoryInterf…...

docker离线搭建仓库

要在Docker中搭建本地仓库&#xff0c;可以按照以下步骤进行操作&#xff1a; 首先安装 Docker。根据不同的操作系统选择合适的版本并完成安装过程。打开命令行工具&#xff08;如Terminal或PowerShell&#xff09;&#xff0c;运行以下命令来创建一个新的容器并将其设置为本地…...

ABC344 A-E题解

文章目录 A题目AC Code&#xff1a; B题目AC Code&#xff1a; C题目AC Code&#xff1a; D题目AC Code&#xff1a; E题目AC Code&#xff1a; 不易不难&#xff0c;写到5题很简单&#xff0c;但是要有足够的思维能力。 A 题目 我们用一个 flag 变量记录我们是不是在两个竖…...

Jeecg-boot 初次启动项目失败

1.将IDEA的字符编码全部改成utf-8 2. 更改database的密码 3.换个jdk重新启动...

封装的echarts子组件使用watch监听option失效的问题

项目场景&#xff1a; 我在项目里面封装了一个echarts组件&#xff0c;组件接收一个来自外部的option,然后我用了一个watch函数去监听这个option的变化&#xff0c;option变化之后&#xff0c;销毁&#xff0c;然后再新建一个charts表 碎碎念 问题如标题所示&#xff0c;这篇…...

爬虫入门到精通_框架篇14(PySpider架构概述及用法详解)

官方文档 Sample Code&#xff1a; from pyspider.libs.base_handler import *class Handler(BaseHandler):crawl_config {}# minutes24 * 60&#xff1a;每隔一天重新爬取every(minutes24 * 60)def on_start(self):self.crawl(http://scrapy.org/, callbackself.index_page)…...

WPF DataGrid常用属性

AlternationCount属性&#xff1a;表示有几行不同的颜色来回替换&#xff0c;如果设置2则表示有两个颜色交替循环 AutoGenerateColumns属性&#xff1a;是否生成列 CanUserAddRows属性&#xff1a;用户是否可以添加行 CanUserDeleteRows属性&#xff1a;用户是否可以删除行 …...

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Stepper)

步骤导航器组件&#xff0c;适用于引导用户按照步骤完成任务的导航场景。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 仅能包含子组件StepperItem。 接口 Stepper(value?: { index?…...

Python基础语法:基本数据类型(列表)

现实世界中总是存在一组一组的事物。"组"的概念作为基本数据类型的一种&#xff0c;它也是来源于我们去解决现实生活中的一些问题而产生的。它需要有“组”这样的一个数据类型来丰富我们的基本数据类型。 那么在Python中如何来表示“组”的概念呢&#xff1f; 在Py…...

神经网络线性量化方法简介

可点此跳转看全篇 目录 神经网络量化量化的必要性量化方法简介线性对称量化线性非对称量化方法神经网络量化 量化的必要性 NetworkModel size (MB)GFLOPSAlexNet2330.7VGG-1652815.5VGG-1954819.6ResNet-50983.9ResNet-1011707.6ResNet-15223011.3GoogleNet271.6InceptionV38…...

阿里云k8s内OSS报错UnKnownHost。

这个问题就是链接不上oss属于网络问题&#xff1a; 1.排查服务器 在服务器&#xff08;ecs&#xff09;上直接ping oss地址看是否能够通。 不通就要修改dns和hosts&#xff08;这个不说&#xff0c;自己网上查&#xff09; 2.排查容器 进去ping一下你的容器是否能访问到oss…...

nginx的使用,homebrew安装及使用nginx。

Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;它提供了诸如 IMAP、POP3 和 SMTP 等邮件代理服务。以下是 Nginx 的主要作用&#xff1a;12345 作为 Web 服务器。Nginx 能够以较少的系统资源提供高效率的服务&#xff0c;尤其在高并发连接下表现出色。1…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...