news 2026/8/24 15:25:41

关于公交路线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
关于公交路线

更高效的公交最少乘车次数规划:基于邻接矩阵 + 广度优先搜索的优化算法

摘要:日常公交出行规划中,“最少换乘(最少乘车次数)” 是用户最核心的需求之一。传统的全量遍历 BFS 算法在路线数量较多时效率偏低,本文基于 “邻接矩阵 + 哈希表预处理” 的思路,优化了公交路线间的换乘关系存储方式,结合广度优先搜索(BFS)实现了更高效的最少乘车次数计算。

一、为什么要优化?

之前我们组写过一个 “全量遍历” 的公交最少换乘算法,核心是每次搜索都遍历所有路线,判断能不能换乘。这个思路虽然好懂,但有个问题 ——路线多了就变慢。

比如一个城市有 100 条公交线,每次找换乘路线都要遍历 100 条,反复做 “检查两条路线有没有公共站点” 的操作,相当于做了大量重复计算。就像你查公交时,每找一次换乘都要把所有线路翻一遍,效率肯定高不了。

那能不能换个思路?提前把所有路线之间的换乘关系记下来,比如用一张 “路线换乘表”,想知道路线 A 和路线 B 能不能换乘,直接查表就行,不用每次都去比对站点。这就是本文算法的核心 —— 先预处理,再搜索,把 “重复劳动” 提前做完,让搜索过程更高效。

二、核心思路:先 “建表”,再 “搜路”

整个算法可以分成两大步:

预处理阶段:用哈希表记录 “每个站点对应哪些路线”,用邻接矩阵记录 “哪些路线之间可以换乘”—— 相当于提前建好两张关键的表;

BFS 搜索阶段:以 “路线” 为节点,利用建好的邻接矩阵,逐层搜索能到达终点的路线,找到最少乘车次数。

这个思路的本质是:用预处理的时间换搜索的时间,尤其适合需要多次查询的场景(比如同一个公交网络查不同起点终点)。

三、先搞懂几个关键 “工具”

在看代码之前,先把算法里用到的核心数据结构和概念说清楚,不然容易看懵。

3.1 哈希表(unordered_map):快速找 “经过某站的所有路线”

哈希表的特点是 “键值对存储,查询速度快”,这里我们用它存:

键:站点编号(比如 1、5、7);

值:经过这个站点的所有路线编号(比如经过站点 5 的路线有 0、2、3)。

举个例子,rec[5] = [0,2,3],意思是 “站点 5 被路线 0、路线 2、路线 3 经过”。有了这个表,想知道 “哪些路线能到起点 S”,直接查rec[S]就行,不用遍历所有路线,这是第一个优化点。

3.2 邻接矩阵:快速判断 “两条路线能不能换乘”

邻接矩阵是一个二维数组edge,edge[i][j] = true表示 “路线 i 和路线 j 可以换乘”,false则表示不能。

比如有 3 条路线,邻接矩阵可能长这样:

路线

0

1

2

0

1

2

意思是:路线 0 和 1 能换乘,路线 1 和 2 能换乘,路线 0 和 2 不能换乘。有了这个矩阵,判断两条路线能不能换乘,只需要查一下矩阵的值,不用再遍历站点比对,这是第二个优化点。

3.3 距离数组(dis):记录 “坐几条线能到这条路线”

dis数组的下标是路线编号,值是 “从起点出发,最少坐几条线能到这条路线”。比如dis[2] = 3,意思是 “从起点到路线 2,最少需要坐 3 条公交线(换乘 2 次)”。

初始时dis数组全设为 - 1(表示没访问过),只有经过起点的路线,dis值设为 1(坐 1 条线就能到)。

四、代码逻辑拆解:一步步看懂

接下来我们把代码掰开揉碎,从预处理到搜索,每一步都讲清楚。

4.1 第一步:特殊情况处理 —— 起点就是终点

如果输入的起点 S 和终点 T 是同一个站,直接返回 0,不用查任何路线,这是最基础的优化。

if (S == T) {

return 0;}

4.2 第二步:预处理 1—— 构建哈希表和邻接矩阵

这是整个算法最核心的预处理步骤,目的是建好 “站点 - 路线” 表和 “路线 - 换乘” 表。

(1)初始化数据结构

int n = routes.size(); // 总路线数// 邻接矩阵:n行n列,初始全为false(不能换乘)

vector<vector<bool>> edge(n, vector<bool>(n, false));// 哈希表:键=站点,值=经过该站点的路线列表

unordered_map<int, vector<int>> rec;

(2)遍历所有路线,填充哈希表和邻接矩阵

for (int i = 0; i < n; i++) { // 遍历第i条路线

for (int stop : routes[i]) { // 遍历第i条路线的每个站点

// 关键:如果这个站点之前被其他路线经过过,说明这些路线和当前路线i能换乘

for (int j : rec[stop]) {

edge[i][j] = edge[j][i] = true; // 标记i和j可换乘(双向)

}

// 把当前路线i加入这个站点的路线列表

rec[stop].push_back(i);

}}

举个例子帮你理解:

先处理路线 0,站点是 [1,3,5]:

站点 1:rec 里没有,直接把路线 0 加入 rec [1];

站点 3:rec 里没有,直接把路线 0 加入 rec [3];

站点 5:rec 里没有,直接把路线 0 加入 rec [5];

再处理路线 1,站点是 [5,7,9]:

站点 5:rec 里有路线 0,所以标记 edge [1][0] = edge [0][1] = true;然后把路线 1 加入 rec [5];

站点 7:rec 里没有,加入 rec [7];

站点 9:rec 里没有,加入 rec [9]。

这样一来,我们就知道路线 0 和 1 能换乘(因为都经过站点 5),邻接矩阵里对应的位置就变成了 true。

4.3 第三步:预处理 2—— 初始化 BFS 队列和距离数组

vector<int> dis(n, -1); // 距离数组,初始-1(未访问)

queue<int> que; // BFS队列,存路线编号

// 把所有经过起点S的路线加入队列,作为BFS的起点for (int bus : rec[S]) {

dis[bus] = 1; // 坐1条线就能到这条路线

que.push(bus);}

比如起点 S 是 1,rec [1] = [0],那么 dis [0] = 1,队列里加入 0。

4.4 第四步:BFS 核心搜索 —— 找最少乘车次数

这一步的逻辑很简单:从经过起点的路线出发,逐层找能换乘的路线,记录每条路线的最少乘车次数。

while (!que.empty()) { // 队列不为空就继续

int x = que.front(); // 取出队首的路线x

que.pop(); // 弹出队首

for (int y = 0; y < n; y++) { // 遍历所有路线y

// 条件1:路线x和y能换乘;条件2:路线y没被访问过

if (edge[x][y] && dis[y] == -1) {

dis[y] = dis[x] + 1; // 乘车次数+1

que.push(y); // 把y加入队列,继续搜索

}

}}

还是举例子:

队列里初始是路线 0,dis [0]=1;

取出路线 0,遍历所有路线 y:

y=1:edge [0][1]=true,dis [1]=-1 → dis [1] = 1+1=2,加入队列;

其他路线:edge [0][y]=false,跳过;

接下来处理队列里的路线 1,继续找能换乘的路线……

4.5 第五步:计算最终结果 —— 找到达终点的最少乘车次数

int ret = INT_MAX; // 初始设为最大整数// 遍历所有经过终点T的路线for (int bus : rec[T]) {

if (dis[bus] != -1) { // 这条路线能到达

ret = min(ret, dis[bus]); // 取最小值

}}// 没找到就返回-1,否则返回最少乘车次数return ret == INT_MAX ? -1 : ret;

比如终点 T 是 9,rec [9] = [1],dis [1]=2 → 最少乘车次数就是 2(换乘 1 次)。

4.6 辅助函数:手动输入路线和站点

这部分代码很简单,就是让用户输入路线数量、每条路线的站点数和站点编号,最终返回一个二维数组routes,比如routes = [[1,3,5],[5,7,9]]。

4.7 主函数:整合所有步骤

主函数的逻辑就是:

调用inputRoutes()让用户输入路线;

输入起点 S 和终点 T;

调用numBusesToDestination()计算最少乘车次数;

输出结果。

下面是全部代码:

更高效的公交最少乘车次数规划:基于邻接矩阵 + 广度优先搜索的优化算法

摘要:日常公交出行规划中,“最少换乘(最少乘车次数)” 是用户最核心的需求之一。传统的全量遍历 BFS 算法在路线数量较多时效率偏低,本文基于 “邻接矩阵 + 哈希表预处理” 的思路,优化了公交路线间的换乘关系存储方式,结合广度优先搜索(BFS)实现了更高效的最少乘车次数计算。

一、为什么要优化?聊聊传统算法的痛点

之前我们组写过一个 “全量遍历” 的公交最少换乘算法,核心是每次搜索都遍历所有路线,判断能不能换乘。这个思路虽然好懂,但有个致命问题 ——路线多了就变慢。

比如一个城市有 100 条公交线,每次找换乘路线都要遍历 100 条,反复做 “检查两条路线有没有公共站点” 的操作,相当于做了大量重复计算。就像你查公交时,每找一次换乘都要把所有线路翻一遍,效率肯定高不了。

那能不能换个思路?提前把所有路线之间的换乘关系记下来,比如用一张 “路线换乘表”,想知道路线 A 和路线 B 能不能换乘,直接查表就行,不用每次都去比对站点。这就是本文算法的核心 —— 先预处理,再搜索,把 “重复劳动” 提前做完,让搜索过程更高效。

二、核心思路:先 “建表”,再 “搜路”

整个算法可以分成两大步:

预处理阶段:用哈希表记录 “每个站点对应哪些路线”,用邻接矩阵记录 “哪些路线之间可以换乘”—— 相当于提前建好两张关键的表;

BFS 搜索阶段:以 “路线” 为节点,利用建好的邻接矩阵,逐层搜索能到达终点的路线,找到最少乘车次数。

这个思路的本质是:用预处理的时间换搜索的时间,尤其适合需要多次查询的场景(比如同一个公交网络查不同起点终点)。

三、先搞懂几个关键 “工具”

在看代码之前,先把算法里用到的核心数据结构和概念说清楚,不然容易看懵。

3.1 哈希表(unordered_map):快速找 “经过某站的所有路线”

哈希表的特点是 “键值对存储,查询速度快”,这里我们用它存:

键:站点编号(比如 1、5、7);

值:经过这个站点的所有路线编号(比如经过站点 5 的路线有 0、2、3)。

举个例子,rec[5] = [0,2,3],意思是 “站点 5 被路线 0、路线 2、路线 3 经过”。有了这个表,想知道 “哪些路线能到起点 S”,直接查rec[S]就行,不用遍历所有路线,这是第一个优化点。

3.2 邻接矩阵:快速判断 “两条路线能不能换乘”

邻接矩阵是一个二维数组edge,edge[i][j] = true表示 “路线 i 和路线 j 可以换乘”,false则表示不能。

比如有 3 条路线,邻接矩阵可能长这样:

路线

0

1

2

0

1

2

意思是:路线 0 和 1 能换乘,路线 1 和 2 能换乘,路线 0 和 2 不能换乘。有了这个矩阵,判断两条路线能不能换乘,只需要查一下矩阵的值,不用再遍历站点比对,这是第二个优化点。

3.3 距离数组(dis):记录 “坐几条线能到这条路线”

dis数组的下标是路线编号,值是 “从起点出发,最少坐几条线能到这条路线”。比如dis[2] = 3,意思是 “从起点到路线 2,最少需要坐 3 条公交线(换乘 2 次)”。

初始时dis数组全设为 - 1(表示没访问过),只有经过起点的路线,dis值设为 1(坐 1 条线就能到)。

四、代码逻辑拆解:一步步看懂

接下来我们把代码掰开揉碎,从预处理到搜索,每一步都讲清楚。

4.1 第一步:特殊情况处理 —— 起点就是终点

如果输入的起点 S 和终点 T 是同一个站,直接返回 0,不用查任何路线,这是最基础的优化。

if (S == T) {

return 0;}

4.2 第二步:预处理 1—— 构建哈希表和邻接矩阵

这是整个算法最核心的预处理步骤,目的是建好 “站点 - 路线” 表和 “路线 - 换乘” 表。

(1)初始化数据结构

int n = routes.size(); // 总路线数// 邻接矩阵:n行n列,初始全为false(不能换乘)

vector<vector<bool>> edge(n, vector<bool>(n, false));// 哈希表:键=站点,值=经过该站点的路线列表

unordered_map<int, vector<int>> rec;

(2)遍历所有路线,填充哈希表和邻接矩阵

for (int i = 0; i < n; i++) { // 遍历第i条路线

for (int stop : routes[i]) { // 遍历第i条路线的每个站点

// 关键:如果这个站点之前被其他路线经过过,说明这些路线和当前路线i能换乘

for (int j : rec[stop]) {

edge[i][j] = edge[j][i] = true; // 标记i和j可换乘(双向)

}

// 把当前路线i加入这个站点的路线列表

rec[stop].push_back(i);

}}

举个例子帮你理解:

先处理路线 0,站点是 [1,3,5]:

站点 1:rec 里没有,直接把路线 0 加入 rec [1];

站点 3:rec 里没有,直接把路线 0 加入 rec [3];

站点 5:rec 里没有,直接把路线 0 加入 rec [5];

再处理路线 1,站点是 [5,7,9]:

站点 5:rec 里有路线 0,所以标记 edge [1][0] = edge [0][1] = true;然后把路线 1 加入 rec [5];

站点 7:rec 里没有,加入 rec [7];

站点 9:rec 里没有,加入 rec [9]。

这样一来,我们就知道路线 0 和 1 能换乘(因为都经过站点 5),邻接矩阵里对应的位置就变成了 true。

4.3 第三步:预处理 2—— 初始化 BFS 队列和距离数组

vector<int> dis(n, -1); // 距离数组,初始-1(未访问)

queue<int> que; // BFS队列,存路线编号

// 把所有经过起点S的路线加入队列,作为BFS的起点for (int bus : rec[S]) {

dis[bus] = 1; // 坐1条线就能到这条路线

que.push(bus);}

比如起点 S 是 1,rec [1] = [0],那么 dis [0] = 1,队列里加入 0。

4.4 第四步:BFS 核心搜索 —— 找最少乘车次数

这一步的逻辑很简单:从经过起点的路线出发,逐层找能换乘的路线,记录每条路线的最少乘车次数。

while (!que.empty()) { // 队列不为空就继续

int x = que.front(); // 取出队首的路线x

que.pop(); // 弹出队首

for (int y = 0; y < n; y++) { // 遍历所有路线y

// 条件1:路线x和y能换乘;条件2:路线y没被访问过

if (edge[x][y] && dis[y] == -1) {

dis[y] = dis[x] + 1; // 乘车次数+1

que.push(y); // 把y加入队列,继续搜索

}

}}

还是举例子:

队列里初始是路线 0,dis [0]=1;

取出路线 0,遍历所有路线 y:

y=1:edge [0][1]=true,dis [1]=-1 → dis [1] = 1+1=2,加入队列;

其他路线:edge [0][y]=false,跳过;

接下来处理队列里的路线 1,继续找能换乘的路线……

4.5 第五步:计算最终结果 —— 找到达终点的最少乘车次数

int ret = INT_MAX; // 初始设为最大整数// 遍历所有经过终点T的路线for (int bus : rec[T]) {

if (dis[bus] != -1) { // 这条路线能到达

ret = min(ret, dis[bus]); // 取最小值

}}// 没找到就返回-1,否则返回最少乘车次数return ret == INT_MAX ? -1 : ret;

比如终点 T 是 9,rec [9] = [1],dis [1]=2 → 最少乘车次数就是 2(换乘 1 次)。

4.6 辅助函数:手动输入路线和站点

这部分代码很简单,就是让用户输入路线数量、每条路线的站点数和站点编号,最终返回一个二维数组routes,比如routes = [[1,3,5],[5,7,9]]。

4.7 主函数:整合所有步骤

主函数的逻辑就是:

调用inputRoutes()让用户输入路线;

输入起点 S 和终点 T;

调用numBusesToDestination()计算最少乘车次数;

输出结果。

五、举个完整例子:算法怎么跑?

用一个具体的例子,把整个流程走一遍,你就全懂了。

输入

路线数量:2

路线 1(索引 0):1 3 5

路线 2(索引 1):5 7 9

起点 S=1,终点 T=9

执行过程

特殊情况:S≠T,继续;

预处理哈希表和邻接矩阵:

rec[1] = [0],rec[3] = [0],rec[5] = [0,1],rec[7] = [1],rec[9] = [1];

edge[0][1] = edge[1][0] = true;

初始化 BFS:

rec [S=1] = [0] → dis [0] = 1,队列加入 0;

BFS 搜索:

取出队列里的 0,遍历 y=0 到 1:

y=1:edge [0][1]=true,dis [1]=-1 → dis [1] = 2,队列加入 1;

计算结果:

rec[T=9] = [1],dis[1]=2 → ret=2;

输出:最少需要乘坐 2 辆公交车(换乘 1 次)。

六、优化点对比:为什么这个算法更快?

和之前的全量遍历算法比,这个优化版本的核心优势在两个地方:

对比项

传统全量遍历算法

邻接矩阵 + 哈希表优化算法

找经过站点的路线

遍历所有路线,逐个检查站点

哈希表直接查,O (1) 级别的速度

判断两条路线能否换乘

遍历站点比对,重复计算

邻接矩阵直接查,O (1) 级别的速度

整体效率

O (n²*m)(n = 路线数,m = 站点数)

O (n² + 总站点数)

简单说,传统算法是 “用到了再算”,优化算法是 “提前算好,用到了直接查”,路线越多,优化效果越明显。

七、算法的优缺点和改进方向

7.1 优点

效率高:预处理后,搜索过程几乎没有重复计算,适合路线多的场景;

逻辑清晰:预处理 + 搜索的两步走,分工明确,容易理解;

实用性强:哈希表和邻接矩阵都是常用数据结构,代码容易落地。

7.2 缺点

空间开销:邻接矩阵的空间复杂度是 O (n²),如果路线数 n 特别大(比如 1000 条),矩阵会占用较多内存;

只算次数,不返回路线:这个算法只能算出最少坐几条线,但没法返回具体的路线顺序(比如路线 0→路线 1),如果需要输出路线,还得在 BFS 里记录路径;

不考虑站点数:和之前的算法一样,只关注乘车次数,不考虑总坐多少站。

7.3 改进方向

优化空间:把邻接矩阵换成邻接表(比如vector<vector<int>> adj),只存能换乘的路线,节省内存;

记录具体路线:在 BFS 时,用一个数组prev记录每条路线的上一条路线,最后回溯出完整的路线序列;

多目标优化:加入站点数的权重,比如 “乘车次数 ×2 + 总站点数”,用加权 BFS 找综合最优解。

八、总结

这篇文章讲的算法,核心是 “提前预处理,减少重复计算”—— 用哈希表快速定位 “站点对应的路线”,用邻接矩阵快速判断 “路线能否换乘”,再结合 BFS 的逐层搜索,高效找到最少乘车次数。

相比于传统的全量遍历算法,这个优化版本在路线数量较多时优势明显,而且逻辑并不复杂,只要理解了 “哈希表存站点 - 路线”“邻接矩阵存路线 - 换乘” 这两个核心点,就能轻松上手。

五、举个完整例子:算法怎么跑?

用一个具体的例子,把整个流程走一遍,你就全懂了。

输入

路线数量:2

路线 1(索引 0):1 3 5

路线 2(索引 1):5 7 9

起点 S=1,终点 T=9

执行过程

特殊情况:S≠T,继续;

预处理哈希表和邻接矩阵:

rec[1] = [0],rec[3] = [0],rec[5] = [0,1],rec[7] = [1],rec[9] = [1];

edge[0][1] = edge[1][0] = true;

初始化 BFS:

rec [S=1] = [0] → dis [0] = 1,队列加入 0;

BFS 搜索:

取出队列里的 0,遍历 y=0 到 1:

y=1:edge [0][1]=true,dis [1]=-1 → dis [1] = 2,队列加入 1;

计算结果:

rec[T=9] = [1],dis[1]=2 → ret=2;

输出:最少需要乘坐 2 辆公交车(换乘 1 次)。

六、优化点对比:为什么这个算法更快?

和之前的全量遍历算法比,这个优化版本的核心优势在两个地方:

对比项

传统全量遍历算法

邻接矩阵 + 哈希表优化算法

找经过站点的路线

遍历所有路线,逐个检查站点

哈希表直接查,O (1) 级别的速度

判断两条路线能否换乘

遍历站点比对,重复计算

邻接矩阵直接查,O (1) 级别的速度

整体效率

O (n²*m)(n = 路线数,m = 站点数)

O (n² + 总站点数)

简单说,传统算法是 “用到了再算”,优化算法是 “提前算好,用到了直接查”,路线越多,优化效果越明显。

七、算法的优缺点和改进方向

7.1 优点

效率高:预处理后,搜索过程几乎没有重复计算,适合路线多的场景;

逻辑清晰:预处理 + 搜索的两步走,分工明确,容易理解;

实用性强:哈希表和邻接矩阵都是常用数据结构,代码容易落地。

7.2 缺点

空间开销:邻接矩阵的空间复杂度是 O (n²),如果路线数 n 特别大(比如 1000 条),矩阵会占用较多内存;

只算次数,不返回路线:这个算法只能算出最少坐几条线,但没法返回具体的路线顺序(比如路线 0→路线 1),如果需要输出路线,还得在 BFS 里记录路径;

不考虑站点数:和之前的算法一样,只关注乘车次数,不考虑总坐多少站。

7.3 改进方向

优化空间:把邻接矩阵换成邻接表(比如vector<vector<int>> adj),只存能换乘的路线,节省内存;

记录具体路线:在 BFS 时,用一个数组prev记录每条路线的上一条路线,最后回溯出完整的路线序列;

多目标优化:加入站点数的权重,比如 “乘车次数 ×2 + 总站点数”,用加权 BFS 找综合最优解。

八、总结

这篇文章讲的算法,核心是 “提前预处理,减少重复计算”—— 用哈希表快速定位 “站点对应的路线”,用邻接矩阵快速判断 “路线能否换乘”,再结合 BFS 的逐层搜索,高效找到最少乘车次数。

相比于传统的全量遍历算法,这个优化版本在路线数量较多时优势明显,而且逻辑并不复杂,只要理解了 “哈希表存站点 - 路线”“邻接矩阵存路线 - 换乘” 这两个核心点,就能轻松上手。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/24 13:32:40

香港科技大学突破视频编辑:让AI真正“理解“而非“模仿“视频变换

想象你正在观看一段海边的视频&#xff0c;画面中有一艘橙色的小船在平静的海湾中漂浮。现在如果你对AI说"想象这艘船一小时后离开的场景"&#xff0c;你觉得AI会怎么做&#xff1f;大多数现有的视频编辑AI可能会简单地让船消失&#xff0c;或者随便移动一下位置。但…

作者头像 李华
网站建设 2026/8/24 13:32:02

文泉驿微米黑字体:3分钟完成全平台安装与配置指南

文泉驿微米黑字体&#xff1a;3分钟完成全平台安装与配置指南 【免费下载链接】fonts-wqy-microhei Debian package for WenQuanYi Micro Hei (mirror of https://anonscm.debian.org/git/pkg-fonts/fonts-wqy-microhei.git) 项目地址: https://gitcode.com/gh_mirrors/fo/fo…

作者头像 李华
网站建设 2026/8/23 18:00:59

告别局域网限制!宝塔 FTP+cpolar 让文件管理随时随地

前言 宝塔 FTP 主要用于服务器文件的上传、下载和管理&#xff0c;支持通过可视化界面创建账号、分配目录权限&#xff0c;方便团队成员按权限操作文件&#xff0c;是服务器运维中常用的工具。 作为经常需要管理多台服务器的运维人员&#xff0c;我觉得宝塔 FTP 最大的优点是…

作者头像 李华
网站建设 2026/8/24 14:32:27

Stacked U-Nets: A No-Frills Approach to Natural Image Segmentation

文章目录AbstractIntroductionRelated WorkUse of Pre-Trained NetsU-Nets RevisitedU-Net Module ImplementationSUNets: Stacked U-Nets for ClassificationDilated SUNets for SegmentationDilationMultigridDe-gridding FiltersExperimentsDiscussion and Conclusionpaperc…

作者头像 李华
网站建设 2026/8/23 15:14:06

加热片与加热棒的介绍及推荐场景

我们来详细对比一下模拟电路和电源设计中常见的两种加热元件&#xff1a;加热片​ 和 加热棒&#xff0c;并分析它们的核心差异及适用场景。 一、核心概念和结构 加热片&#xff1a;​ 一种扁平、薄片状的加热元件。通常由电阻加热材料&#xff08;如合金箔、导电油墨、厚膜电…

作者头像 李华
网站建设 2026/8/24 8:19:36

【MYSQL】字符串拼接和参数化sql语句区别

总结&#xff1a;参数化不是为了复用查询结果&#xff0c; 而是为了固定 SQL 结构&#xff0c;让解析和执行行为可预测&#xff1b; 同时通过语义隔离彻底消除 SQL 注入。字符串拼接&#xff1a; var ids string.Join(",", idList);var sql $" SELECT * FROM …

作者头像 李华