重言式判别程序设计:从表达式树到真值表的完整实现
简介本资源是一份面向计算机专业本科生的数据结构课程设计实践材料聚焦重言式逻辑恒等式的程序化判别实现解决布尔表达式真值恒定性验证这一典型算法与数据结构综合应用问题。压缩包共4个文件含2份Word文档含完整设计思路、二叉树建模方法、后序遍历栈协同求值算法详解及测试用例和2个C语言源码文件chyan_sks.c为核心判别程序支持变量赋值枚举与全真值表验证总大小仅38KB轻量易读便于教学复现与代码剖析。已有381人学习下载适合课程设计参考、算法课设答辩准备或数据结构中树与栈综合应用的深度理解。读者可直接运行C代码验证逻辑结合文档掌握从表达式建模、二叉树构建、后序遍历执行到重言式判定的全流程实现细节并获得规范的课程设计报告撰写范式。1. 重言式判别程序课程设计不是写个 if-else 就完事而是把命题逻辑的“真值表黑匣子”真正拆开、跑通、验得过你手头正赶着一份《离散数学》或《逻辑与程序设计》的课程设计任务题目写着“重言式判别程序”心里却在打鼓这玩意儿到底要判什么是简单套个 eval() 把表达式扔进去就算交差还是得从原子命题开始一层层构造真值表、遍历所有赋值组合、再逐行验证结果列全为真——答案是后者。这份课程设计的核心价值不在于输出“是/否”而在于显式建模命题逻辑的语义结构括号匹配怎么处理运算符优先级如何嵌套否定、合取、析取、蕴含、等价五种联结词的真值函数怎么无歧义实现更关键的是如何让程序自己发现“这个公式无论怎么赋值都为真”这个全局性质。它本质是一次小型编译器前端实践词法分析提取命题变元、语法分析构建表达式树、语义求值真值表生成与遍历。适合刚学完栈、二叉树、递归回溯的学生也适合想补足形式化思维落地能力的开发者。本文带你从零手撸一个可验证、可调试、能覆盖¬(p∨q)↔(¬p∧¬q)这类德·摩根律公式的完整实现。2. 从命题逻辑到代码为什么必须用表达式树而不是字符串 eval()2.1 为什么 eval() 是条死胡同安全、语义、可扩展三重雷区很多同学第一反应是用 Python 的eval()或 JavaScript 的eval()直接执行用户输入的逻辑表达式字符串比如eval(not (p or q) (not p and not q))。这看似省事但立刻踩进三个硬坑安全雷eval()允许任意代码执行用户输入__import__(os).system(rm -rf /)就直接炸库语义雷编程语言的and/or/not与逻辑学中的∧/∨/¬在短路求值、操作数类型上存在隐式转换如0 and 1返回0而非False导致真值表计算失真可扩展雷当需要支持→蕴含或↔等价时Python 没有原生运算符硬塞会混淆逻辑等价与数值相等且无法统一处理优先级p → q ∨ r应理解为p → (q ∨ r)而非(p → q) ∨ r。提示课程设计评分标准里“未使用 eval 等危险函数”往往是基础分项。用表达式树既是技术选择也是得分底线。2.2 表达式树命题逻辑的天然数据结构重言式判别的数学本质是对一个合式公式WFF在所有可能的命题变元赋值下求值。而 WFF 天然具有递归结构公式 :: 原子命题 | ¬公式 | (公式 ∧ 公式) | (公式 ∨ 公式) | (公式 → 公式) | (公式 ↔ 公式)这直接映射为二叉树对一元¬可视为左子树为空的特例叶节点命题变元如p,q,r内部节点联结词¬,∧,∨,→,↔左右子树该联结词的操作对象这种结构带来三大实操优势优先级固化树的深度天然体现运算优先级无需手动处理括号和运算符栈遍历即求值后序遍历LRN可自然实现自底向上求值变量提取可控中序遍历叶子节点去重后即得全部命题变元为真值表列数提供依据。2.3 手动构建表达式树词法分析 递归下降解析我们不依赖 ANTLR 等重型工具用纯 Python 实现轻量解析器。核心是两个函数def tokenize(expr): 将字符串切分为原子 token变量名、括号、联结词 # 移除空格按字符扫描合并连续字母如 pq → p,q但 p1 视为单变量 tokens [] i 0 while i len(expr): c expr[i] if c.isalpha(): # 命题变元单字母 a-z, A-Z tokens.append(c) elif c in (): tokens.append(c) elif c ¬: tokens.append(¬) elif c ∧: tokens.append(∧) elif c ∨: tokens.append(∨) elif c →: tokens.append(→) elif c ↔: tokens.append(↔) i 1 return tokens def parse_expression(tokens, pos0): 递归下降解析返回 (node, new_pos) if pos len(tokens): raise SyntaxError(Unexpected end of expression) token tokens[pos] if token.isalpha(): # 原子命题 return TreeNode(VAR, valuetoken), pos 1 elif token ¬: # 一元否定 pos 1 child, pos parse_expression(tokens, pos) return TreeNode(NOT, leftchild), pos elif token (: # 二元运算( A op B ) pos 1 left, pos parse_expression(tokens, pos) if pos len(tokens) or tokens[pos] not in [∧, ∨, →, ↔]: raise SyntaxError(fExpected operator after {left.value}, got {tokens[pos] if pos len(tokens) else EOF}) op tokens[pos] pos 1 right, pos parse_expression(tokens, pos) if pos len(tokens) or tokens[pos] ! ): raise SyntaxError(fExpected ), got {tokens[pos] if pos len(tokens) else EOF}) pos 1 return TreeNode(op, leftleft, rightright), pos else: raise SyntaxError(fUnexpected token: {token})参数说明tokenize()严格按字符切分不尝试识别多字母变量如p1避免课程设计复杂度溢出若需支持可扩展为正则r[a-zA-Z][a-zA-Z0-9]*parse_expression()使用递归下降pos参数实现无状态解析new_pos返回解析结束位置支撑嵌套调用TreeNode类需定义typeVAR/NOT/∧等、value仅 VAR 有、left/right子树指针这是后续求值的基础。这段代码的血泪经验是不要试图用正则一次匹配整个表达式。逻辑表达式嵌套深、括号多正则难以维护且易出错。递归下降虽代码稍长但逻辑清晰、错误定位准、扩展性强加新联结词只需改if分支。3. 真值表生成与重言式判定遍历所有赋值拒绝“差不多就行”3.1 提取命题变元从中序遍历到去重列表表达式树建好后第一步是找出所有出现的命题变元这是真值表列数的依据def get_variables(node): 中序遍历提取所有 VAR 节点的 value返回去重有序列表 vars_set set() def inorder(n): if n is None: return if n.type VAR: vars_set.add(n.value) else: inorder(n.left) if n.right: # NOT 节点无 right其他都有 inorder(n.right) inorder(node) return sorted(list(vars_set)) # 排序确保每次顺序一致方便测试 # 示例parse((p ∧ q) ∨ ¬r) → vars [p,q,r]为什么必须排序真值表行序依赖变量排列顺序。[q,p,r]和[p,q,r]生成的赋值序列不同导致同一公式在不同运行中判定结果不一致这是调试噩梦。排序是低成本、高确定性的工程习惯。3.2 生成全赋值组合位运算是最稳的穷举法n 个变量共 2^n 种赋值。用位运算生成简洁且无浮点误差def generate_assignments(vars_list): 返回所有赋值字典的列表如 [{p:True,q:False}, ...] n len(vars_list) assignments [] for i in range(2**n): # 0 到 2^n - 1 assignment {} for j, var in enumerate(vars_list): # i 的第 j 位0→False, 1→True bit (i j) 1 assignment[var] bool(bit) assignments.append(assignment) return assignments # 示例vars[p,q] → [ {p:False,q:False}, {p:True,q:False}, # {p:False,q:True}, {p:True,q:True} ]关键细节j从 0 开始对应变量列表索引i j右移j位 1取最低位完美映射二进制位不用itertools.product([True,False], repeatn)因后者生成顺序依赖 Python 版本而位运算顺序绝对稳定字典键为变量名值为布尔后续求值时可直接assign[p]访问。3.3 树节点求值后序遍历 真值函数查表定义每个联结词的真值函数封装为字典避免冗长if-elifTRUTH_TABLE { ¬: lambda a: not a, ∧: lambda a, b: a and b, ∨: lambda a, b: a or b, →: lambda a, b: (not a) or b, # 蕴含仅当 aT,bF 时为 F ↔: lambda a, b: a b, # 等价同真或同假 } def evaluate(node, assignment): 后序遍历求值叶节点查 assignment内部节点查 TRUTH_TABLE if node.type VAR: return assignment[node.value] elif node.type NOT: val evaluate(node.left, assignment) return TRUTH_TABLE[¬](val) else: # 二元运算∧, ∨, →, ↔ left_val evaluate(node.left, assignment) right_val evaluate(node.right, assignment) return TRUTH_TABLE[node.type](left_val, right_val)为什么→要写成(not a) or b这是逻辑蕴含的标准定义。学生常误写为a and b合取或a b等价必须明确区分。此处用函数查表未来加新联结词只需扩TRUTH_TABLE不碰主逻辑。3.4 重言式判定全真即重言一假即非重言最后一步遍历所有赋值记录每行结果汇总判定def is_tautology(root, variables): 判定是否重言式所有赋值下求值均为 True assignments generate_assignments(variables) results [] for assign in assignments: try: res evaluate(root, assign) results.append(res) except Exception as e: print(fEvaluation error for {assign}: {e}) return False, [] is_taut all(results) return is_taut, results # 主流程调用示例 # tokens tokenize((p → q) ∨ (q → p)) # root, _ parse_expression(tokens) # vars get_variables(root) # taut, vals is_tautology(root, vars) # print(fIs tautology: {taut}) # True # print(fTruth values: {vals}) # [True, True, True, True]输出设计考量返回(bool, list)二元组既给出判定结果又返回完整真值列方便学生对照手算表格验证try-except捕获求值异常如变量未定义避免程序崩溃提升课程设计鲁棒性。4. 避坑指南五个让老师皱眉、让调试崩溃的真实问题4.1 括号不匹配导致解析中断现象、原因与解决现象输入(p ∧ q ∨ r)时解析器报错SyntaxError: Expected )或静默生成错误树。原因原始parse_expression()仅处理(A op B)形式但p ∧ q ∨ r本身无外层括号且∧和∨优先级相同需按左结合处理。我们的解析器要求所有二元运算必须显式括号包裹即必须写成((p ∧ q) ∨ r)。解决在课程设计文档中明确要求输入格式为完全括号化表达式Fully Parenthesized Expression这是教学场景下的合理简化。若需支持无括号需引入运算符优先级表和调度场算法Shunting Yard远超课程范围。接受约束比强行扩展更专业。4.2 命题变元命名冲突现象、原因与解决现象输入(p ∧ P)程序提取变量为[p,P]生成 2^24 行真值表但实际p和P应视为同一变量。原因tokenize()按字符区分大小写而逻辑学中变量名不区分大小写p ≡ P。解决在tokenize()中统一转小写tokens.append(c.lower())同时在get_variables()去重前先.lower()。课程设计不必追求工业级健壮但基础一致性必须保证。4.3 蕴含运算符→的键盘输入问题现象、原因与解决现象学生复制粘贴p → q时→符号显示为方块或乱码tokenize()无法识别。原因→是 Unicode 字符U2192部分编辑器/终端不支持或学生用减号-和大于号拼凑-。解决在tokenize()中增加兼容处理elif expr[i:i2] -: # 支持 - 作为 → 的替代 tokens.append(→) i 2 elif expr[i:i2] -: # 支持 - 作为 ↔ 的替代 tokens.append(↔) i 2同时在文档中注明“推荐使用-和-系统自动转换为逻辑符号”。降低使用门槛是课程设计交付物的基本素养。4.4 真值表行数指数爆炸现象、原因与解决现象输入含 10 个变量的公式程序卡死或内存溢出。原因2^10 1024 行尚可但 2^20 ≈ 100 万行2^30 ≈ 10 亿行穷举不可行。解决在is_tautology()开头添加检查if len(variables) 12: raise ValueError(fToo many variables ({len(variables)}). Max supported is 12 (4096 rows).)并在文档中说明“本程序采用真值表法适用于变量数 ≤12 的公式。更大规模问题需用语义表或归结原理超出本课程设计范围。”坦诚边界比假装能处理更可信。4.5 否定符¬与减号-混淆现象、原因与解决现象输入-p程序报错SyntaxError: Unexpected token: -。原因tokenize()只识别¬未处理 ASCII 减号-。解决在tokenize()中将-映射为¬elif c -: # 检查后一个字符是否为字母避免误伤负数但逻辑式无负数 if i1 len(expr) and expr[i1].isalpha(): tokens.append(¬) i 1 # 跳过下一个字母不只跳过 -字母由后续循环处理 else: tokens.append(-) # 其他情况保留但逻辑式中不应出现更稳妥做法文档中强制要求使用¬并提供 Windows 输入法快捷键Alt8704或 Mac 字符查看器培养学生规范表达习惯。5. 进阶验证与教学延伸用反例和等价性检验你的程序是否真可靠5.1 反例驱动测试不止验证重言式更要揪出非重言式的反例课程设计验收时老师常问“如果判定为非重言式能否给出一个让它为假的赋值” 这要求程序不仅能回答“否”还要返回反例。修改is_tautology()即可def is_tautology_with_counterexample(root, variables): assignments generate_assignments(variables) for assign in assignments: try: res evaluate(root, assign) if not res: # 找到第一个使公式为假的赋值 return False, assign # 返回反例 except Exception as e: print(fEvaluation error for {assign}: {e}) return False, None return True, None # 全为真无反例 # 调用 # taut, counter is_tautology_with_counterexample(root, vars) # if taut: # print(Tautology confirmed.) # else: # print(fNot tautology. Counterexample: {counter}) # e.g., {p:True, q:False}为什么这步不能省重言式定义是“所有赋值下为真”证伪只需一个反例。返回反例是程序逻辑完备性的直接证明比单纯返回False有力得多。这也是离散数学作业的常规要求。5.2 逻辑等价性检验用重言式判定器验证定律重言式判别器的最高阶用法是验证两个公式是否逻辑等价A ↔ B是重言式当且仅当A和B等价。构建一个等价检验函数def are_equivalent(formula_a, formula_b): 检验 formula_a ↔ formula_b 是否为重言式 # 构造 (A ↔ B) full_expr f({formula_a}) ↔ ({formula_b}) tokens tokenize(full_expr) try: root, _ parse_expression(tokens) vars get_variables(root) return is_tautology_with_counterexample(root, vars)[0] except Exception as e: print(fParse or eval error: {e}) return False # 测试德·摩根律 # are_equivalent(¬(p ∨ q), (¬p ∧ ¬q)) # True # are_equivalent(p → q, ¬p ∨ q) # True教学价值这让学生亲手验证教材中的逻辑定律把抽象公式变成可执行、可验证的代码。比起背诵亲手证伪一个错误等式如p → qvsp ∧ q印象更深。我在带课程设计时总要求学生至少验证 3 条教材定律并截图真值表提交。5.3 真值表可视化生成 Markdown 表格直观看清判定过程为方便报告撰写和老师审阅将真值表导出为 Markdown 表格def print_truth_table(root, variables): 打印真值表 Markdown 格式 assignments generate_assignments(variables) headers variables [Result] rows [] for assign in assignments: row [str(assign[v]) for v in variables] res evaluate(root, assign) row.append(str(res)) rows.append(row) # 打印表头 print(| | .join(headers) |) print(| |.join([---] * len(headers)) |) # 打印数据行 for row in rows: print(| | .join(row) |) # 调用print_truth_table(root, [p,q]) # 输出 # | p | q | Result | # |---|---|--------| # | False | False | True | # | True | False | False | # | False | True | True | # | True | True | True |为什么坚持 Markdown.docx表格易格式错乱.csv需额外打开Markdown 可直接粘贴到实验报告、GitHub README 或 Jupyter Notebook 中零成本复用。从那以后我每次课程设计答辩都强制走一遍print_truth_table()把生成的表格截图放进 PPT —— 老师一眼看懂你的程序干了什么比讲一百行代码都管用。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

C++ Qt词法分析器课设:NFA/DFA状态图可视化与完整实现

C++ Qt词法分析器课设:NFA/DFA状态图可视化与完整实现

简介:一套面向编译原理课程与期末课设场景的C/Qt词法分析器工程包,适合正在学习词法分析、自动机理论与GUI开发的学生参考。工具将源代码拆分为标记(token),覆盖关键字、标识符、数字、运算符等常见规则,并…

2026/10/10 14:31:25 阅读更多 →
Python神经网络赛车游戏实战:从零搭建到训练避坑

Python神经网络赛车游戏实战:从零搭建到训练避坑

简介:这份资源面向神经网络与强化学习入门者,以及希望用Python动手实践AI控制游戏的开发者,核心是用两种方式实现神经网络操纵赛车游戏:一是基于TensorFlow框架搭建训练模型,二是不依赖框架、从零手写DNN,帮…

2026/10/10 14:31:25 阅读更多 →
基于Python的虚假新闻检测多模态识别:源代码与文档说明

基于Python的虚假新闻检测多模态识别:源代码与文档说明

简介:这份资源面向计算机相关专业的本科生与研究生,提供一套基于Python的虚假新闻检测多模态识别完整项目源码,可用于毕业设计、期末大作业或课程设计场景,帮助解决多模态特征融合与虚假新闻分类的实践难题。压缩包共39个文件&…

2026/10/10 14:31:25 阅读更多 →

最新新闻

WSL升级报错Could not write value to key?注册表权限修复全指南

WSL升级报错Could not write value to key?注册表权限修复全指南

如果你也在升级 WSL 时撞上Could not write value to key \SOFTWARE\Classes\Drive\shell\WSL这条报错,先别急着怀疑系统坏了。这个错误出现在 WSL 安装程序向注册表写入资源管理器右键菜单项的阶段,大部分时候不是某个发行版出了问题,而是注…

2026/10/10 16:50:18 阅读更多 →
ClawX v0.1.23:OpenClaw图形化填坑版,20分钟跑通本地大模型

ClawX v0.1.23:OpenClaw图形化填坑版,20分钟跑通本地大模型

ClawX v0.1.23 出来有几天了,这次更新我愿称之为“史诗级填坑版”。如果你之前折腾过 OpenClaw 系工具,大概率卡在过这几个地方:命令行看得头脑发懵、依赖装到一半报错、模型下载到 80% 断掉、好不容易跑起来界面又黑屏。这版 ClawX 基本把这…

2026/10/10 16:50:18 阅读更多 →
LAS点云训练PointNet分类:从数据预处理到模型调优全流程指南

LAS点云训练PointNet分类:从数据预处理到模型调优全流程指南

简介:针对PointNet/PointNet训练自定义LAS点云数据的需求,这套基于PyTorch的代码包提供了完整的分类与语义分割流程。资源以GitHub开源项目Pointnet_Pointnet2_pytorch为基础,重点适配带Classification属性的LAS点云数据,读者可在…

2026/10/10 16:50:18 阅读更多 →
Dify私有化部署实战:Linux服务器+Docker Compose指南

Dify私有化部署实战:Linux服务器+Docker Compose指南

开头从一次真实的部署说起。有段时间我在Linux服务器上反复折腾容器应用,最头疼的还不是容器本身,而是应用之间的依赖关系、初始化顺序、数据卷到底应该怎么挂。后来接触到一个叫 Dify 的开源项目,发现它的定位很有意思:不是普通聊…

2026/10/10 16:50:18 阅读更多 →
回归算法实现家庭用电预测:特征工程与避坑指南

回归算法实现家庭用电预测:特征工程与避坑指南

简介:这是一份机器学习回归算法实战资源,面向数据科学初学者与需要完成课程项目的学生,旨在解决家庭用电量预测问题。资源系统覆盖线性回归、多项式回归、决策树回归、随机森林回归与支持向量回归等主流算法,并涉及缺失值处理、异…

2026/10/10 16:50:18 阅读更多 →
ComfyUI SDXL+Refiner精炼工作流:把出图质感从能看拉到耐看

ComfyUI SDXL+Refiner精炼工作流:把出图质感从能看拉到耐看

简介:ComfyUI/SDXL Refiner 精炼文生图工作流,是一份面向ComfyUI初中级用户的文生图节点流程配置,专门应对SDXL基础模型生成图像时细节表现不足、需要二次精炼出图的场景。压缩包内共1个json格式工作流文件,包体仅4KB&#xff0c…

2026/10/10 16:49:17 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →