C++实现迪杰斯特拉算法:从原理到高性能工程实践
1. 从地图导航到网络路由迪杰斯特拉算法为何如此重要如果你用过手机地图App规划路线或者配置过网络路由器那么你其实已经间接使用了迪杰斯特拉算法。这个由荷兰计算机科学家艾兹赫尔·迪杰斯特拉在1956年提出的算法是解决单源最短路径问题的经典方法。简单来说就是在一个带权重的图中从一个指定的起点出发找到到达图中所有其他顶点的最短路径和距离。听起来有点抽象想象一下你是一个快递员手里有一张城市地图上面标明了每条道路的通行时间权重你的任务是从仓库起点出发计算出到达每一个客户地址的最短时间路径。迪杰斯特拉算法就是帮你高效完成这个计算的“最强大脑”。为什么我们要用C来实现它在算法竞赛、高性能计算以及一些对执行效率要求极高的底层系统如网络路由协议OSPF、IS-IS的核心中C因其接近硬件的性能和对内存的精细控制而成为首选。用C实现迪杰斯特拉不仅能让你透彻理解算法的每一个细节——比如优先队列如何优化、邻接表如何存储图——更能让你亲手打磨出一个在百万级节点图上依然能快速响应的工具。这对于深入理解数据结构、图论以及性能优化至关重要。接下来我将带你从零开始用C实现一个工业级强度的迪杰斯特拉算法并分享我在实际项目中踩过的坑和优化技巧。2. 算法核心思想与设计思路拆解迪杰斯特拉算法的核心是一种“贪心”策略。它维护一个集合里面存放的是已经找到最短路径的顶点。算法从起点开始每一步都从“未确定最短路径的顶点集合”中挑选一个离起点距离最短的顶点加入“已确定集合”并利用这个新确定的顶点作为“跳板”去更新它所有邻居顶点到起点的距离估计。这个过程反复进行直到所有顶点都被处理完毕或者找到目标顶点的最短路径。2.1 为什么“贪心”在这里是有效的关键在于图的权重必须是非负的。如果存在负权边这个“当前最短即全局最短”的假设就不成立了贪心策略会失效这时就需要使用Bellman-Ford等能处理负权的算法。迪杰斯特拉的贪心保证了每次从候选集中选出的顶点其当前距离就是最终的最短距离不会再被后续的更新所改变。这就像你在一片迷雾森林中每次只点亮离你最近的那盏灯被点亮的区域已确定最短路径就永远不会再变暗你的视野已知的最短路径集合就这样稳步而确定地向外扩张。2.2 数据结构选型邻接表与优先队列实现这个算法我们需要选择合适的数据结构来存储图和辅助计算。图的存储邻接表 vs. 邻接矩阵对于稀疏图边数远小于顶点数的平方邻接表在空间和时间效率上都具有压倒性优势。迪杰斯特拉算法需要频繁遍历一个顶点的所有出边邻接表正好对应O(1)的访问开销。而邻接矩阵需要遍历整行对于稀疏图会产生大量无效操作。因此在绝大多数实际场景如道路网络、社交网络中我们都使用邻接表。// 使用vector实现的邻接表每个顶点对应一个链表存储其邻接顶点和边权 struct Edge { int to; // 目标顶点 int weight; // 边权重 Edge(int t, int w) : to(t), weight(w) {} }; vectorvectorEdge graph;核心辅助数据结构优先队列堆算法的效率瓶颈在于每一步如何快速从“未确定集合”中找出距离起点最近的那个顶点。如果每次都用线性扫描算法复杂度将是O(V²)。迪杰斯特拉最初的论文也止步于此。而现代的实现无一例外地使用优先队列通常用最小堆实现来优化这个查找过程将复杂度降至O((VE) log V)这对于大型图来说是质的飞跃。C标准库中的priority_queue就是一个现成的工具。3. 手把手实现从零构建C代码让我们抛开理论直接进入实战。我将分步构建一个完整的、可复用的迪杰斯特拉算法实现。3.1 基础框架与输入处理首先我们定义图的结构和必要的辅助数组。#include iostream #include vector #include queue #include climits // 用于INT_MAX using namespace std; typedef pairint, int pii; // first: 距离, second: 顶点编号 class Dijkstra { private: int V; // 顶点数 vectorvectorpii adj; // 邻接表存储 (邻居顶点, 边权) public: Dijkstra(int vertices) : V(vertices) { adj.resize(V); } // 添加一条从u到v的有向边权重为w void addEdge(int u, int v, int w) { adj[u].emplace_back(v, w); // 如果是无向图需要同时添加反向边 // adj[v].emplace_back(u, w); } };这里使用vectorvectorpairint, int作为邻接表。pairint, int的第一个元素是目标顶点to第二个元素是边权重weight。使用emplace_back可以避免临时对象的构造效率更高。3.2 核心算法函数实现接下来是算法的核心函数shortestPath。vectorint shortestPath(int src) { // 1. 初始化距离数组 vectorint dist(V, INT_MAX); dist[src] 0; // 2. 初始化优先队列最小堆 // C的priority_queue默认是最大堆所以需要greaterpii来构造最小堆 priority_queuepii, vectorpii, greaterpii pq; pq.emplace(0, src); // (距离, 顶点) // 3. 核心循环 while (!pq.empty()) { // 取出当前距离起点最近的顶点 int currentDist pq.top().first; int u pq.top().second; pq.pop(); // 关键优化懒惰删除 // 如果从队列中取出的距离大于当前记录的距离说明这个记录是过时的直接跳过 if (currentDist dist[u]) { continue; } // 遍历u的所有出边 for (const auto edge : adj[u]) { int v edge.first; int weight edge.second; // 松弛操作 if (dist[v] dist[u] weight) { dist[v] dist[u] weight; pq.emplace(dist[v], v); } } } return dist; }代码逐行解析距离数组distdist[i]存储从起点src到顶点i的当前已知最短距离。初始时起点距离为0其他均为无穷大INT_MAX。优先队列pq存储待处理的顶点以该顶点到起点的当前估计距离为优先级。我们使用最小堆保证每次弹出的都是距离最小的顶点。核心循环pq.top()和pq.pop()取出当前距离最小的顶点u。“懒惰删除”技巧这是实现中的一个关键优化点。由于我们更新一个顶点的距离时是直接向优先队列插入一个新记录而不是更新旧记录。队列中可能同时存在同一个顶点的多个不同距离的记录。当我们从队列顶部取出一个顶点时如果它的距离值currentDist大于dist[u]当前记录的最短距离说明这个记录是旧的、无效的直接跳过。这避免了在堆中进行复杂的修改或删除操作极大地简化了代码并保持了效率。松弛操作对于u的每个邻居v检查如果通过u到达v的路径比当前已知的dist[v]更短就更新dist[v]并将新的(dist[v], v)对压入优先队列。3.3 路径重建功能上面的函数只返回了最短距离。在实际应用中我们往往还需要知道具体的路径。我们可以通过增加一个parent数组来记录路径。pairvectorint, vectorint shortestPathWithTrace(int src) { vectorint dist(V, INT_MAX); vectorint parent(V, -1); // 记录前驱顶点用于重建路径 dist[src] 0; priority_queuepii, vectorpii, greaterpii pq; pq.emplace(0, src); while (!pq.empty()) { int currentDist pq.top().first; int u pq.top().second; pq.pop(); if (currentDist dist[u]) continue; for (const auto edge : adj[u]) { int v edge.first; int weight edge.second; // 松弛操作 if (dist[v] dist[u] weight) { dist[v] dist[u] weight; parent[v] u; // 记录v是从u过来的 pq.emplace(dist[v], v); } } } return {dist, parent}; } // 根据parent数组重建从src到target的路径 vectorint getPath(const vectorint parent, int target) { vectorint path; if (parent[target] -1 target ! 0) { // 假设起点是0这里需要根据实际情况调整 return path; // 不可达 } for (int v target; v ! -1; v parent[v]) { path.push_back(v); } reverse(path.begin(), path.end()); return path; }4. 实战测试与复杂度分析4.1 编写测试用例理论再好跑不通也是白搭。我们用一个经典的图来测试我们的实现。int main() { // 创建一个有5个顶点的图 (0, 1, 2, 3, 4) Dijkstra d(5); // 添加边 (有向图) d.addEdge(0, 1, 4); d.addEdge(0, 2, 1); d.addEdge(2, 1, 2); d.addEdge(1, 3, 1); d.addEdge(2, 3, 5); d.addEdge(3, 4, 3); int src 0; auto result d.shortestPathWithTrace(src); vectorint dist result.first; vectorint parent result.second; cout 从顶点 src 出发到各顶点的最短距离:\n; for (int i 0; i dist.size(); i) { if (dist[i] INT_MAX) cout 顶点 i : 不可达\n; else { cout 顶点 i : 距离 dist[i] , 路径: ; vectorint path getPath(parent, i); for (int j 0; j path.size(); j) { cout path[j]; if (j ! path.size() - 1) cout - ; } cout endl; } } return 0; }预期输出从顶点 0 出发到各顶点的最短距离: 顶点 0: 距离 0, 路径: 0 顶点 1: 距离 3, 路径: 0 - 2 - 1 顶点 2: 距离 1, 路径: 0 - 2 顶点 3: 距离 4, 路径: 0 - 2 - 1 - 3 顶点 4: 距离 7, 路径: 0 - 2 - 1 - 3 - 4你可以手动验证一下这个结果是否正确。从0到1直接走权重为4的边不如走0-2(1) 2-1(2) 3这条路径短。4.2 时间复杂度与空间复杂度分析时间复杂度O((V E) log V)每个顶点最多被加入优先队列一次懒惰删除保证了过时记录被跳过每次push或pop操作是 O(log V)。每条边最多被遍历一次用于松弛操作。因此总复杂度是 O((V E) log V)。对于稠密图E ≈ V²这比朴素的 O(V²) 实现要好得多。空间复杂度O(V E)主要用于存储邻接表 O(V E)。距离数组和父节点数组各 O(V)。优先队列在最坏情况下可能存储 O(E) 个条目虽然平均远小于此但通常仍记为 O(E)。5. 高级优化与工程实践要点基础的实现已经完成但要将其用于真实项目还需要考虑更多细节。5.1 使用自定义节点结构优化优先队列标准库的priority_queue存储pairint, int在比较时需要创建临时对象。对于性能极其敏感的场景我们可以定义自定义结构体并重载比较运算符有时能带来小幅性能提升。struct Node { int id; int dist; // 重载 运算符用于构造最小堆 bool operator (const Node other) const { return dist other.dist; } }; // 使用 priority_queueNode, vectorNode, greaterNode pq;5.2 处理大规模图使用更快的堆C标准库的priority_queue底层是二叉堆。对于顶点数巨大例如超过百万的图使用d-叉堆d-ary heap或斐波那契堆Fibonacci Heap理论上可以获得更好的常数优化。虽然斐波那契堆的摊还复杂度在降低键值操作上是 O(1)但其实现复杂常数因子大在大多数实际应用中经过高度优化的二叉堆如std::priority_queue或四叉堆表现更佳。除非你在进行非常专业的图算法库开发否则std::priority_queue足矣。5.3 邻接表存储的细微差别我们之前用了vectorvectorpairint, int。对于静态图这很好。但如果图是动态的频繁增删边vector的扩容可能导致内存重分配和迭代器失效。此时可以考虑使用list或者每个顶点使用一个独立的forward_list单链表虽然缓存局部性稍差但修改操作更稳定。// 使用list存储邻接表适用于频繁修改边的场景 vectorlistpii adj;5.4 并行化探索迪杰斯特拉算法本质上是顺序的因为每一步都依赖于上一步确定的最短顶点。但在一些变种或特定场景下可以进行并行化。例如在GPU上实现时可以在同一轮松弛中并行处理当前已确定顶点集合的所有出边。但这属于高级话题需要对算法和硬件架构有很深的理解。6. 常见问题排查与调试技巧即使理解了原理实现时也难免遇到问题。下面是我在多年实践中总结的一些常见坑点和调试方法。6.1 算法运行结果不对问题现象可能原因排查方法距离全部是无穷大(INT_MAX)起点设置错误图是有向的但按无向图添加了边或反之。1. 检查src参数是否正确传入。2. 仔细核对addEdge的调用确认边的方向是否符合图的性质。部分顶点距离错误权重输入错误松弛条件判断写反。1. 打印或调试查看图的邻接表结构确认每条边的权重。2. 检查if (dist[v] dist[u] weight)这个条件确保是“如果新路径更短则更新”。程序陷入死循环或崩溃图中存在负权边优先队列的排序规则错误导致逻辑混乱图的顶点索引越界。1.绝对确保图中没有负权边。迪杰斯特拉不能处理负权。2. 检查priority_queue的声明确认使用了greaterpii构造最小堆。3. 在addEdge和访问adj[u]前加入边界检查assert(u 0 u V)。重要提示迪杰斯特拉算法绝对不能处理带有负权边的图。如果图中存在负权算法会得出错误的结果甚至可能陷入死循环因为可以通过反复走负权边无限降低“距离”。对于含负权的图请使用 Bellman-Ford 或 SPFA 算法。6.2 性能瓶颈分析当图规模很大时程序可能运行很慢。使用性能分析工具如gprof(Linux) 或 Visual Studio Profiler找到热点函数。通常时间会花在优先队列的操作和边的遍历上。检查数据结构确认使用的是邻接表而非邻接矩阵。对于稀疏图邻接矩阵是性能杀手。输入/输出优化如果是从文件读入巨大的图数据如竞赛题目cin/cout可能成为瓶颈。可以关闭同步流或使用scanf/printf。ios::sync_with_stdio(false); cin.tie(nullptr);内存访问模式vector的连续内存访问对CPU缓存友好性能通常优于list。除非需要频繁中间插入删除否则优先使用vector。6.3 内存占用过大对于顶点数极多上亿的图内存是关键。压缩邻接表如果边权重是固定类型如int可以使用vectorpairint, int。如果顶点编号范围很大但不连续可以考虑使用mapint, int存储邻接关系但查询效率会下降。使用位集表示距离如果距离范围有限可以考虑更紧凑的数据类型如short或unsigned short。外部存储算法当图无法完全装入内存时需要考虑基于磁盘的图算法这属于高级专题。7. 从算法到应用场景扩展思考掌握基础实现后我们可以思考如何将其应用到更复杂的场景中这也是面试中常被深入考察的点。7.1 多源最短路径与最近设施查找迪杰斯特拉是单源的。如何快速找到图中离多个起点中任意一个最近的顶点例如在一个城市中有多家医院要找到离你最近的医院。解决方案建立一个超级源点。虚拟一个额外的顶点从这个超级源点到每家医院连一条权重为0的边。然后以这个超级源点为起点跑一次迪杰斯特拉算法。这样得到的dist数组dist[i]就是顶点i到最近一家医院的距离。这种方法的时间复杂度和跑一次单源迪杰斯特拉是一样的非常高效。7.2 带约束的最短路径有时最短路径需要满足额外条件比如路径上不能经过某些顶点或者总权重不能超过某个值又或者需要在路径中收集某些物品。解决方案这类问题通常需要修改状态定义。例如可以将状态定义为(当前顶点, 已满足的约束条件)然后将图转化为一个状态空间图在这个新的图上跑迪杰斯特拉或其他搜索算法。这其实就是动态规划与图搜索的结合例如经典的“带状态压缩的旅行商问题TSP”的解法思想。7.3 在动态规划中的应用许多动态规划问题可以转化为图上的最短路径问题。将每个状态看作图中的一个顶点状态之间的转移看作有向边转移的代价就是边的权重。那么求初始状态到目标状态的最小代价就等价于求图上的最短路径。迪杰斯特拉算法在这种情况下可以作为一种高效的DP求解器特别是当状态转移图是稀疏的时候。实现一个正确的迪杰斯特拉算法是基本功但理解其变体和应用场景才能让你在解决复杂问题时游刃有余。我个人的体会是算法学习不能停留在“默写模板”的层面多思考“如果条件变了该怎么办”并亲手去实现和验证才是提升工程能力和算法思维的正道。最后一个小技巧在调试复杂图算法时尝试将一个小规模例子的整个运行过程每一步的dist数组、优先队列内容手工模拟或打印出来与你的程序输出对比这是定位逻辑错误最直接有效的方法。

相关新闻

1.02英寸电子墨水屏驱动全解析:从SPI接口到低功耗项目实战

1.02英寸电子墨水屏驱动全解析:从SPI接口到低功耗项目实战

1. 从一块“会变色的纸”说起:1.02英寸电子墨水屏的独特魅力如果你玩过树莓派、Arduino或者STM32,大概率见过各种LED、LCD甚至OLED屏幕。它们色彩鲜艳,刷新飞快,是显示动态信息的绝佳选择。但今天我想聊点不一样的——一块只有1.0…

2026/8/1 18:19:09 阅读更多 →
机器学习模型训练可视化:从损失曲线到过拟合诊断的完整指南

机器学习模型训练可视化:从损失曲线到过拟合诊断的完整指南

在机器学习项目(MLP)的实践过程中,对模型训练过程进行可视化分析是提升模型性能和理解模型行为的关键环节。通过系统性地评估和展示模型在训练集和验证集上的损失(Loss)和准确率(Accuracy)等关键…

2026/8/1 18:18:09 阅读更多 →
专业级PL-2303旧版芯片Windows驱动解决方案:如何让停产硬件重获新生

专业级PL-2303旧版芯片Windows驱动解决方案:如何让停产硬件重获新生

专业级PL-2303旧版芯片Windows驱动解决方案:如何让停产硬件重获新生 【免费下载链接】pl2303-win10 Windows 10 driver for end-of-life PL-2303 chipsets. 项目地址: https://gitcode.com/gh_mirrors/pl/pl2303-win10 在工业自动化、实验室设备和传统制造领…

2026/8/1 18:18:09 阅读更多 →

最新新闻

ElasticSearch wildcard查询(英文检索)

ElasticSearch wildcard查询(英文检索)

wildcard查询允许使用通配符 * 和 ? 来进行模糊匹配: * 代表0个或多个字符 ? 代表任意1个字符 以下是两个查询示例: GET /lib3/user/_search {"query": {"wildcard": {"name": "*zhao*"}} } GET /lib3/user/_search {"quer…

2026/8/1 19:07:28 阅读更多 →
6款AI写作辅助平台汇总

6款AI写作辅助平台汇总

真正的学术 AI,从不替你代笔,而是做你的选题军师、文献管家、逻辑教练、润色专家。从中文毕业论文到英文期刊发表,从框架搭建到降重合规,这 6 款工具覆盖全场景,帮你用最低时间成本,写出高质量、高原创、高…

2026/8/1 19:07:28 阅读更多 →
策略流程闭环:EasyQuant 如何实现策略全生命周期管理

策略流程闭环:EasyQuant 如何实现策略全生命周期管理

引言在量化交易中,策略的生命周期管理是一个复杂而关键的环节。从策略开发、回测、优化到实盘执行,每个环节都需要精心管理和协调。传统的量化平台往往在这些环节之间存在割裂,导致策略落地困难、版本管理混乱、绩效评估不准确等问题。EasyQu…

2026/8/1 19:07:28 阅读更多 →
ElasticSearch fuzzy模糊查询(英文检索)

ElasticSearch fuzzy模糊查询(英文检索)

1. 引言 本文旨在系统性地介绍 Elasticsearch 中 fuzzy(模糊)查询的实现原理、核心参数、使用场景以及最佳实践。通过详细的代码示例和常见问题解答,帮助开发者理解并掌握这一强大的近似匹配工具,以应对实际业务中因拼写错误、输入偏差或数据不一致导致的搜索难题。 2. 核…

2026/8/1 19:07:28 阅读更多 →
AI生成无缝连续图案:从零到量产的7步落地法,92%新手3天内掌握核心技巧

AI生成无缝连续图案:从零到量产的7步落地法,92%新手3天内掌握核心技巧

更多请点击: https://codechina.net 第一章:AI生成无缝连续图案的核心原理与行业价值 AI生成无缝连续图案的本质在于将深度学习建模能力与图像拓扑约束深度融合,其核心是让神经网络在隐空间中学习周期性纹理的不变表示,并通过边界…

2026/8/1 19:07:28 阅读更多 →
如何在5分钟内搭建全能QQ机器人?LuckyLilliaBot终极指南

如何在5分钟内搭建全能QQ机器人?LuckyLilliaBot终极指南

如何在5分钟内搭建全能QQ机器人?LuckyLilliaBot终极指南 【免费下载链接】LuckyLilliaBot 支持 OneBot 11、Satori 和 Milky 协议 项目地址: https://gitcode.com/gh_mirrors/li/LuckyLilliaBot 想要快速搭建一个功能强大的QQ机器人吗?厌倦了复杂…

2026/8/1 19:06:28 阅读更多 →

日新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/8/1 13:02:46 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/8/1 5:19:34 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/8/1 10:33:33 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →