动态规划核心应用:最长公共子序列(LCS)算法详解与C++实现
1. 项目概述从“找不同”到“找相同”的算法思维最近在带新人做算法复盘发现很多朋友对“最长公共子序列”这个概念一听就懂一写就懵。这问题在C面试里尤其是考察动态规划时出场率极高。它不像排序、查找那样直观更像是在玩一个高级版的“找不同”游戏——只不过我们这次要找的是两个字符串之间最长的、可以不连续的“相同”部分。举个例子我们有两个字符串“程序员”和“编码员”。肉眼一看公共部分有“员”也有“程”和“序”吗仔细看“程序员”是“程-序-员”“编码员”是“编-码-员”。它们最长的、可以不连续匹配上的字符序列是什么是“员”。但如果字符串是“abcde”和“ace”那么“a-c-e”这个序列在两个字符串里都存在且顺序一致长度3就是最长公共子序列LCS。为什么它这么重要因为在C开发中尤其是在文本比对如Git的diff算法、生物信息学的DNA序列分析、甚至是我们常用的std::diff算法底层都能看到LCS的影子。它考察的不仅仅是你对字符串操作的熟练度std::string,std::vectorchar更是对动态规划这一核心算法思想的掌握程度。动态规划是解决重叠子问题和最优子结构问题的利器而LCS是其最经典、最教科书式的体现。理解它就等于拿到了解开一大类字符串处理与序列比对问题的钥匙。2. 核心思路拆解为什么动态规划是唯一正解面对“最长公共子序列”这个问题我们首先会想能不能暴力破解假设两个字符串长度分别是m和n那么字符串A的所有子序列有2^m个字符串B有2^n个。我们需要找出所有公共的再比较长度。这个时间复杂度是O(2^(mn))指数级爆炸完全不可行。于是我们退而求其次尝试递归。定义函数LCS(i, j)表示字符串A的前i个字符和字符串B的前j个字符的LCS长度。思路很直接如果A[i-1] B[j-1]那么当前字符可以加入LCS问题规模缩小LCS(i, j) 1 LCS(i-1, j-1)。如果A[i-1] ! B[j-1]那么当前字符不可能同时出现在LCS中我们需要看是放弃A的当前字符好还是放弃B的当前字符好即LCS(i, j) max(LCS(i-1, j), LCS(i, j-1))。这个递归关系非常清晰。但是直接递归实现会有大量的重复计算。比如计算LCS(i, j)时可能需要计算LCS(i-1, j-1)、LCS(i-1, j)和LCS(i, j-1)而后者在计算其他状态时又会被重复计算。这就是动态规划典型的重叠子问题特性。因此动态规划成了自然而然的选择。它的核心是用一张表通常是二维数组dp来存储所有子问题的解从而避免重复计算。dp[i][j]的含义与递归定义一致表示A[0..i-1]和B[0..j-1]的LCS长度。我们通过迭代填充这张表从最小的子问题空字符串开始逐步构建出更大问题的解。注意这里有一个初学者极易混淆的点。dp数组的大小通常是(m1) x (n1)而不是m x n。多出来的那一行一列i0或j0代表一个字符串为空的情况此时LCS长度显然为0。这构成了我们动态规划的“基础情况”Base Case使得递推公式可以从i1, j1开始顺畅运行。3. 动态规划表的构建与递推公式详解理解了为什么用动态规划接下来就是如何构建这张表。我们以字符串A “abcde” B “ace” 为例。首先初始化一个(51) x (31)的二维数组dp即6行4列。并将第一行和第一列全部置为0表示当一个字符串为空时LCS长度为0。dp[i][j]j0 (B空)j1 (‘a’)j2 (‘c’)j3 (‘e’)i0 (A空)0000i1 (‘a’)0i2 (‘b’)0i3 (‘c’)0i4 (‘d’)0i5 (‘e’)0现在我们从i1, j1开始填充。递推公式如下如果 A[i-1] B[j-1]当前字符匹配。那么A[0..i-1]和B[0..j-1]的LCS一定等于A[0..i-2]和B[0..j-2]的LCS再加上当前这个字符。所以dp[i][j] dp[i-1][j-1] 1。如果 A[i-1] ! B[j-1]当前字符不匹配。那么A[0..i-1]和B[0..j-1]的LCS只能来源于两种情况中的最大值忽略A的当前字符dp[i-1][j]A[0..i-2]与B[0..j-1]的LCS忽略B的当前字符dp[i][j-1]A[0..i-1]与B[0..j-2]的LCS所以dp[i][j] max(dp[i-1][j], dp[i][j-1])。我们开始手动推导i1, j1: A[0]’a’, B[0]’a’相等。dp[1][1] dp[0][0] 1 01 1。i1, j2: A[0]’a’, B[1]’c’不等。dp[1][2] max(dp[0][2], dp[1][1]) max(0, 1) 1。i1, j3: A[0]’a’, B[2]’e’不等。dp[1][3] max(dp[0][3], dp[1][2]) max(0, 1) 1。i2, j1: A[1]’b’, B[0]’a’不等。dp[2][1] max(dp[1][1], dp[2][0]) max(1, 0) 1。i2, j2: A[1]’b’, B[1]’c’不等。dp[2][2] max(dp[1][2], dp[2][1]) max(1, 1) 1。i3, j2: A[2]’c’, B[1]’c’相等。dp[3][2] dp[2][1] 1 11 2。… 以此类推。最终填充完的dp表如下dp[i][j]j0j1 (‘a’)j2 (‘c’)j3 (‘e’)i00000i1 (‘a’)0111i2 (‘b’)0111i3 (‘c’)0122i4 (‘d’)0122i5 (‘e’)0123表格右下角dp[5][3] 3就是我们要求的最长公共子序列的长度。这个建表的过程时间复杂度是O(mn)空间复杂度也是O(mn)。对于大多数面试和竞赛场景这个复杂度是可以接受的。4. C代码实现与逐行解析理论清晰了我们用C把它实现出来。这里提供两个版本基础版只求长度和进阶版还原出LCS字符串。4.1 基础版仅计算LCS长度#include iostream #include vector #include string #include algorithm // for max using namespace std; int longestCommonSubsequence(string text1, string text2) { int m text1.length(); int n text2.length(); // 创建 (m1) x (n1) 的二维dp数组并初始化为0 vectorvectorint dp(m 1, vectorint(n 1, 0)); // 填充dp表i和j从1开始对应字符串下标从0开始 for (int i 1; i m; i) { for (int j 1; j n; j) { if (text1[i - 1] text2[j - 1]) { // 字符匹配长度加1 dp[i][j] dp[i - 1][j - 1] 1; } else { // 字符不匹配取上方或左方的最大值 dp[i][j] max(dp[i - 1][j], dp[i][j - 1]); } } } // dp[m][n] 即为最终结果 return dp[m][n]; } int main() { string s1 abcde; string s2 ace; int result longestCommonSubsequence(s1, s2); cout The length of LCS is: result endl; // 输出 3 return 0; }代码解析与注意事项dp数组定义使用vectorvectorint并初始化为0。dp[i][j]表示text1前i个字符和text2前j个字符的LCS长度。i和j为0的行/列代表空串已初始化为0。下标对应关系这是最容易出错的地方。循环中i从1到mj从1到n。但当我们需要比较字符时用的是text1[i-1]和text2[j-1]。因为dp的索引比字符串的索引大1以容纳空串的基础情况。递推逻辑严格遵循上一节推导的公式。相等则左上角1不等则max(上方, 左方)。返回值最终结果存储在dp[m][n]即考虑整个字符串text1和text2。4.2 进阶版构造出LCS字符串只得到长度往往不够我们通常需要知道这个子序列具体是什么。这就需要我们在填充dp表的过程中额外记录路径信息然后在计算完成后反向回溯构造出LCS。#include iostream #include vector #include string #include algorithm using namespace std; string longestCommonSubsequenceStr(string text1, string text2) { int m text1.length(); int n text2.length(); vectorvectorint dp(m 1, vectorint(n 1, 0)); // 可选用一个方向表记录路径1表示来自左上角匹配2表示来自上方3表示来自左方 vectorvectorint direction(m 1, vectorint(n 1, 0)); for (int i 1; i m; i) { for (int j 1; j n; j) { if (text1[i - 1] text2[j - 1]) { dp[i][j] dp[i - 1][j - 1] 1; direction[i][j] 1; // 来自左上角表示匹配 } else { if (dp[i - 1][j] dp[i][j - 1]) { dp[i][j] dp[i - 1][j]; direction[i][j] 2; // 来自上方 } else { dp[i][j] dp[i][j - 1]; direction[i][j] 3; // 来自左方 } } } } // 回溯构造LCS字符串 string lcs; int i m, j n; while (i 0 j 0) { if (direction[i][j] 1) { // 当前字符是匹配的加入结果注意是text1[i-1] lcs.push_back(text1[i - 1]); i--; j--; } else if (direction[i][j] 2) { // 来自上方移动i i--; } else { // direction[i][j] 3 // 来自左方移动j j--; } } // 因为是从后往前构造的需要反转字符串 reverse(lcs.begin(), lcs.end()); return lcs; } int main() { string s1 abcde; string s2 ace; string result longestCommonSubsequenceStr(s1, s2); cout The LCS is: \ result \ with length result.length() endl; // 输出 ace 和 3 return 0; }回溯构造的核心逻辑记录路径在填充dp表时用一个等大的direction表记录每个状态dp[i][j]是从哪个方向转移过来的左上、上、左。从终点开始从dp[m][n]开始即表格的右下角。根据方向回溯如果方向是1左上说明当前text1[i-1]和text2[j-1]是匹配的字符应将其加入LCS然后i--, j--。如果方向是2上说明当前值继承自上方即忽略了text1的当前字符只移动i--。如果方向是3左说明当前值继承自左方即忽略了text2的当前字符只移动j--。反转结果由于是反向回溯得到的字符串是逆序的最后需要reverse一下。实操心得在实际编码中如果不要求输出具体序列可以省略direction表以节省空间。当需要构造序列时direction表是最直观的方法。另一种常见的技巧是不单独记录方向而是直接通过比较dp[i][j]与dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]的值来决定回溯路径代码会稍显复杂但节省了O(m*n)的空间。面试时能清晰说出思路并实现带方向表的版本通常就足够了。5. 空间复杂度优化滚动数组技巧基础解法使用了O(m*n)的二维数组。当字符串长度很大比如上万时这会消耗可观的内存。我们可以观察到在填充dp[i][j]时它只依赖于dp[i-1][j-1]、dp[i-1][j]和dp[i][j-1]。也就是说当前行只依赖于上一行和当前行已计算的部分。因此我们可以将二维数组压缩成两个一维数组分别代表“上一行”和“当前行”。这就是滚动数组的思想。int longestCommonSubsequence_opt(string text1, string text2) { int m text1.length(); int n text2.length(); if (m n) return longestCommonSubsequence_opt(text2, text1); // 让较短的字符串作为text2空间更省 // 只使用两行数组 vectorint prev(n 1, 0); vectorint curr(n 1, 0); for (int i 1; i m; i) { for (int j 1; j n; j) { if (text1[i - 1] text2[j - 1]) { curr[j] prev[j - 1] 1; // 左上角的值在prev[j-1] } else { curr[j] max(prev[j], curr[j - 1]); // 上方是prev[j]左方是curr[j-1] } } // 当前行计算完毕将其作为下一轮的“上一行” swap(prev, curr); // 注意swap后curr变成了旧的prev下一轮循环会覆盖它所以不需要显式清空curr } // 循环结束后最终结果在prev[n]里因为最后进行了一次swap return prev[n]; }优化要点解析prev和currprev代表上一行i-1curr代表当前正在计算的行i。递推公式转换dp[i-1][j-1]-prev[j-1]dp[i-1][j]-prev[j]dp[i][j-1]-curr[j-1](因为curr[j-1]在同一行且已经在本轮循环中计算过了)行交换每计算完一行通过swap(prev, curr)来更新“上一行”的数据为下一轮计算做准备。可选优化代码开头有一个判断确保text2是较短的字符串这样prev和curr数组的长度n1会更小进一步节省空间。空间复杂度从O(m*n)降到了O(min(m, n))。注意事项使用滚动数组后我们失去了完整的历史dp表因此无法再回溯构造出具体的LCS字符串。所以这个优化适用于只需求解长度的问题。如果题目要求输出序列则必须使用完整的二维数组或至少记录路径信息。6. 常见问题、边界条件与调试技巧在实际编写和调试LCS代码时以下几个坑点几乎每个初学者都会遇到。6.1 下标越界与初始化问题访问dp[i-1][j-1]时当i或j为0会导致越界。解决这是为什么dp数组要定义为(m1) x (n1)的根本原因。我们将dp[0][j]和dp[i][0]初始化为0作为基础情况。循环从i1, j1开始确保了所有dp[i-1][*]和dp[*][j-1]的访问都是合法的。相关错误在比较字符时错误地使用text1[i]和text2[j]而不是text1[i-1]和text2[j-1]。牢记dp的索引i,j比字符串索引大1。6.2 空字符串处理问题输入字符串可能为空。解决我们的算法天然支持。如果text1为空(m0)那么dp数组只有一行i0双重循环不会进入直接返回dp[0][n]也就是0。代码是健壮的。但为了更清晰可以在函数开头加入判断if (text1.empty() || text2.empty()) return 0;6.3 字符编码与大小写问题题目是否区分大小写‘A‘和’a‘算相同吗解决这完全取决于题意。标准的LCS问题通常区分大小写。如果题目说明不区分需要在比较前统一转换为小写或大写if (tolower(text1[i-1]) tolower(text2[j-1])) { ... }6.4 内存与性能问题字符串长度非常大10^4级别时O(m*n)的二维数组可能超出内存限制如256MB内存下10000*10000的int数组约400MB。解决首先考虑是否只需求长度。如果是使用滚动数组优化将空间降至O(min(m, n))。如果依然超限可能需要思考是否存在更优的算法对于特殊序列如两个字符串都是同一字符集上的随机序列有基于位运算的优化算法但非常复杂面试极少考察。在竞赛中有时会利用short类型代替int来存储dp值如果长度不超过65535可以减半内存。6.5 调试技巧打印dp表当你的程序输出结果不对时最有效的调试方法就是手动模拟小例子并打印出dp表与你的手动推导表进行对比。// 在填充dp表的循环内或结束后添加打印代码 cout DP Table: endl; for (int i 0; i m; i) { for (int j 0; j n; j) { cout dp[i][j] ; } cout endl; }对比打印出来的表和你在纸上画的表能快速定位是递推公式写错了还是下标处理有问题。7. 变种问题与思路延伸掌握了标准的LCS解法我们可以解决一系列变种问题这些都是面试和笔试中的常客。7.1 最长公共子串区别子串要求是连续的而子序列可以不连续。解法动态规划定义需要改变。定义dp[i][j]为以text1[i-1]和text2[j-1]为结尾的最长公共子串的长度。递推公式如果text1[i-1] text2[j-1]则dp[i][j] dp[i-1][j-1] 1否则dp[i][j] 0因为连续性断了。结果不再是dp[m][n]而是整个dp表中的最大值。同样可以使用滚动数组优化。7.2 最短公共超序列问题给出两个字符串求一个最短的字符串使得这两个字符串都是它的子序列。例如“abac”和“cab”的最短公共超序列可以是“cabac”。思路先求出LCS长度l。那么最短公共超序列的长度就是m n - l。因为超序列需要包含两个字符串的所有字符而LCS部分的字符只需要出现一次。构造超序列的过程可以在回溯LCS路径时完成遇到LCS字符只添加一次非LCS字符则按顺序都添加。7.3 编辑距离问题给定两个单词计算将word1转换成word2所使用的最少操作数插入、删除、替换一个字符。联系编辑距离的dp定义与LCS神似。dp[i][j]表示word1前i个字符转换成word2前j个字符的最少操作数。如果word1[i-1] word2[j-1]无需操作dp[i][j] dp[i-1][j-1]。如果不等则有三种操作选择取最小值插入在word1中插入一个字符匹配word2[j-1]相当于word2的j前进了dp[i][j-1] 1删除删除word1[i-1]相当于word1的i前进了dp[i-1][j] 1替换将word1[i-1]替换为word2[j-1]两者都前进dp[i-1][j-1] 1初始化dp[i][0] i(删除i次)dp[0][j] j(插入j次)。7.4 多个序列的LCS问题求三个或更多字符串的LCS。思路动态规划维度会升高。对于k个字符串需要维护一个k维的dp数组状态转移方程类似但更复杂字符全相等则1否则取所有可能“忽略一个字符串当前字符”状态的最大值。时间和空间复杂度呈指数增长O(n^k)对于k2的情况通常需要更巧妙的算法或只能处理规模很小的问题。8. 在C项目中的实战考量在真实的C项目中实现LCS算法时除了正确性我们还需要考虑一些工程化问题。1. 数据结构选择对于超长字符串例如DNA序列长度可达10^6即使使用滚动数组O(n)的空间也可能很大几MB到几十MB。这时需要评估是否可用更节省空间的数据类型如uint16_t或者是否有流式处理、分块计算的可能。2. 性能热点双重循环是性能瓶颈。在开启编译器优化如-O2后简单的max比较和数组访问会被很好地优化。但在极端性能要求下可以考虑使用一维数组配合临时变量进一步减少缓存不友好。对于特定字符集如DNA的{A,C,G,T}可以利用位图等技巧进行加速但这属于非常专业的优化。3. 代码复用与封装如果项目中多处需要LCS功能应将其封装成一个独立的函数或类。设计清晰的接口例如namespace string_utils { int lcs_length(const std::string a, const std::string b); std::string lcs_sequence(const std::string a, const std::string b); // 或者提供一个模板函数支持不同的字符类型如wstring, vectorchar templatetypename CharT int lcs_length_basic(const std::basic_stringCharT a, const std::basic_stringCharT b); }4. 单元测试为LCS函数编写全面的单元测试至关重要应覆盖以下情况空字符串。完全相同的字符串。完全不同的字符串。一个字符串是另一个的子串。随机生成的中等长度字符串。包含特殊字符空格、标点、Unicode的字符串。5. 与其他算法的结合LCS很少孤立使用。例如在实现一个简单的文本差异对比工具时流程可能是将文本按行分割成两个字符串数组。计算这两个字符串数组的LCS此时每个“字符”是一行文本。根据LCS结果标记出哪些行是相同的哪些行被删除或添加了。理解并熟练运用最长公共子序列的解法不仅仅是解决一道算法题更是培养了一种重要的算法设计思维——动态规划。下次当你遇到诸如“字符串相似度比较”、“最小编辑代价”、“序列对齐”这类问题时不妨先想想它是不是一个穿着“马甲”的LCS问题。

相关新闻

2026最新!商标注册全流程避坑指南,这5个雷区千万别踩

2026最新!商标注册全流程避坑指南,这5个雷区千万别踩

2026最新!商标注册全流程避坑指南,这5个雷区千万别踩2026年6月,《商标法》迎来四十余年来首次全面修订,条文由73条增至87条,将于2027年1月1日起施行-1。新法在收紧注册规则的同时,也赋予了商标管理部门更多…

2026/7/28 4:27:17 阅读更多 →
商标取名总是被驳回?审查员最爱3个命名套路一次讲透

商标取名总是被驳回?审查员最爱3个命名套路一次讲透

商标取名总是被驳回?审查员最爱的3个命名套路一次讲透在深圳,商标驳回率常年居高不下。2026年新《商标法》对商标注册的审查标准进一步收紧——从囤标拦截到显著性审查,全面从严-1-5。很多创业者抱怨:“我取的名字明明很特别&…

2026/7/28 4:27:17 阅读更多 →
创业公司必看:为什么说“市场未动,商标先行

创业公司必看:为什么说“市场未动,商标先行

创业公司必看:为什么说“市场未动,商标先行”是条铁律?“公司名想好了,产品也快上线了,注册商标?不急,等做大了再说。”这是不少深圳创业者的真实想法。但这个看似“省事”的选择,可…

2026/7/28 4:27:17 阅读更多 →

最新新闻

函数依赖是关系数据库规范化理论的核心概念,用于描述关系模式中属性之间的语义约束

函数依赖是关系数据库规范化理论的核心概念,用于描述关系模式中属性之间的语义约束

函数依赖是关系数据库规范化理论的核心概念,用于描述关系模式中属性之间的语义约束。在规范化过程中,从1NF到BCNF的逐级提升,本质是逐步消除不同类型的函数依赖所导致的数据冗余与操作异常(插入、删除、更新异常)。 &a…

2026/7/28 4:41:24 阅读更多 →
AI Agent实战:构建安全可靠的代码生成与执行系统

AI Agent实战:构建安全可靠的代码生成与执行系统

最近在筹备一个面向2026年的技术峰会项目,团队内部讨论最热烈的议题之一就是如何利用AI Agent技术,打造一个能实时生成、演示甚至交互的“代码秀”环节。这不仅仅是简单的代码补全或片段展示,而是希望构建一个能理解需求、自主编码、解释逻辑…

2026/7/28 4:41:24 阅读更多 →
CrowdReply MCP:基于MCP协议的AI生成内容SEO优化实践指南

CrowdReply MCP:基于MCP协议的AI生成内容SEO优化实践指南

在实际 AI 应用开发中,我们经常遇到一个痛点:AI 模型生成的回答内容质量很高,但在搜索引擎中的可见度却很低。这导致很多有价值的对话内容无法被后续用户检索到,形成信息孤岛。CrowdReply MCP 正是为了解决这一问题而设计的工具&a…

2026/7/28 4:41:24 阅读更多 →
Python规则引擎实战:构建可自定义的随机点名与智能分组工具

Python规则引擎实战:构建可自定义的随机点名与智能分组工具

1. 项目缘起:从“随机点名”到“可自定义”的思考 做老师的朋友,或者经常组织团队活动、线上会议的朋友,大概都体会过“随机点名”这个场景的尴尬。要么是临时找个在线网站,功能单一还可能有广告;要么是手动写一堆纸条…

2026/7/28 4:41:24 阅读更多 →
Go语言构建3D游戏世界:从引擎选型到自由探索实现

Go语言构建3D游戏世界:从引擎选型到自由探索实现

1. 项目概述:为什么选择Go来构建3D世界? 如果你在2024年还在犹豫是否要用Go语言来做游戏开发,尤其是3D游戏,那我可以很负责任地告诉你:现在正是时候。过去几年,Go在游戏服务器、工具链和后端服务领域已经证…

2026/7/28 4:41:24 阅读更多 →
TI bq294502二级过压保护芯片EVM实战解析与BMS冗余安全设计

TI bq294502二级过压保护芯片EVM实战解析与BMS冗余安全设计

1. 项目概述与核心价值在锂离子电池应用领域,无论是我们日常使用的电动工具、无人机,还是更大规模的储能系统,安全永远是悬在头顶的“达摩克利斯之剑”。电池管理系统(BMS)作为电池的“大脑”和“保镖”,其…

2026/7/28 4:40:23 阅读更多 →

日新闻

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:43 阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:43 阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:43 阅读更多 →

周新闻

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

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

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

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

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

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

2026/7/27 6:31:56 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

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

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

2026/7/27 4:01:12 阅读更多 →

月新闻