中缀转后缀表达式:调度场算法原理与Python实现详解
1. 表达式转换从人类思维到机器指令的桥梁我们每天都在和表达式打交道无论是心算“3加5乘以2”还是在计算器上输入“35*2”。对我们来说中缀表达式操作符在操作数中间是最自然、最直观的写法。但如果你尝试过用代码去解析和计算一个包含括号和多种运算符的字符串表达式比如“10 2 * 3 / 4”你就会立刻发现这对计算机来说是个相当棘手的任务。它需要处理运算符优先级、括号匹配、从左到右扫描时的回溯问题逻辑会变得异常复杂。这就是为什么在编译原理、计算器设计乃至某些脚本引擎中我们很少直接让计算机去处理中缀表达式。相反我们会先将它转换成两种更“机器友好”的形式前缀表达式或后缀表达式。这两种表达式完全消除了括号和优先级判断的需要计算过程变得像流水线一样清晰、确定。理解这三种表达式的转换与求值不仅是学习栈这一数据结构的绝佳案例更是深入理解计算机如何“思考”算术问题的钥匙。无论你是正在备战技术面试还是希望夯实算法基础亦或是好奇计算器背后的原理掌握这部分内容都将让你受益匪浅。2. 三种表达式形态深度解析2.1 中缀表达式人类的自然语言中缀表达式是我们最熟悉的数学书写方式其标准定义是*操作符如 , -,, /位于两个操作数之间。例如“A B”、“3 * 5 - 2”。它的核心特点在于依赖运算符优先级和括号来明确运算顺序。乘除高于加减括号内的运算优先。这种表达方式符合人类的阅读和思维习惯但给计算机带来了两个主要挑战优先级处理扫描表达式时遇到一个操作符不能立即计算必须看后面是否有更高优先级的操作符。括号嵌套需要栈来匹配左右括号处理嵌套的复杂逻辑。正是这些挑战促使我们寻找对计算机更友好的替代方案。2.2 前缀表达式波兰表达式操作符先行前缀表达式又称波兰表达式由波兰数学家扬·武卡谢维奇提出。其规则是操作符位于两个操作数之前。例如中缀表达式 “A B” 的前缀形式是 “ A B”。 更复杂的例子“(3 5) * 2” 转换成前缀是 “* 3 5 2”。求值过程从右至左扫描前缀表达式的求值算法清晰地展现了栈的“后进先出”特性。从右向左扫描表达式。遇到操作数直接压入栈。遇到操作符从栈顶弹出两个操作数注意顺序先弹出的是右操作数后弹出的是左操作数根据操作符进行计算并将结果压回栈中。重复步骤2-3直到表达式最左端。最后栈中唯一的元素就是表达式的值。以 “ 3 5 2” 为例*扫描2- 压栈[2]扫描5- 压栈[2, 5]扫描3- 压栈[2, 5, 3]扫描- 弹出3(右) 和5(左)计算5 3 8压栈[2, 8]扫描*- 弹出8(右) 和2(左)计算2 * 8 16压栈[16]结果16注意前缀表达式求值时先弹出的操作数是运算符的右操作数这一点与我们的直觉相反是编码时极易出错的地方。2.3 后缀表达式逆波兰表达式操作符殿后后缀表达式也叫逆波兰表达式是目前应用最广泛的一种形式许多虚拟机和计算器内部都采用它。其规则是操作符位于两个操作数之后。例如“A B” 的后缀形式是 “A B ”。 “(3 5) * 2” 的后缀形式是 “3 5 2 *”。求值过程从左至右扫描后缀表达式的求值逻辑更符合我们的直觉也更容易实现。从左向右扫描表达式。遇到操作数直接压入栈。遇到操作符从栈顶弹出两个操作数注意顺序先弹出的是右操作数后弹出的是左操作数进行计算并将结果压回栈中。重复步骤2-3直到表达式结束。栈中唯一的元素即为结果。*以 “3 5 2” 为例扫描3- 压栈[3]扫描5- 压栈[3, 5]扫描- 弹出5(右) 和3(左)计算3 5 8压栈[8]扫描2- 压栈[8, 2]扫描*- 弹出2(右) 和8(左)计算8 * 2 16压栈[16]结果16后缀表达式消除了括号求值顺序唯一算法简单且高效是计算机处理算术表达式的理想形式。3. 中缀转后缀调度场算法实战将人类习惯的中缀表达式转换为机器喜爱的后缀表达式最经典、最清晰的算法是艾兹赫尔·戴克斯特拉提出的调度场算法。这个算法的核心思想是使用两个数据结构一个输出队列用于存放最终的后缀表达式和一个操作符栈用于临时存放操作符并处理优先级。算法步骤详解初始化创建一个空栈用于操作符一个空列表或队列用于输出。从左到右扫描中缀表达式的每个元素token。处理操作数如果是数字或变量直接加入输出队列。处理左括号如果是左括号(直接压入操作符栈。处理右括号如果是右括号)则不断将栈顶的操作符弹出并加入输出队列直到遇到左括号(。弹出左括号丢弃不加入输出。处理操作符最核心的逻辑如果是操作符如,-,*,/则需要比较其与栈顶操作符的优先级。只要栈非空且栈顶不是左括号且当前操作符的优先级 栈顶操作符的优先级就不断将栈顶操作符弹出并加入输出队列。这一步确保了高优先级的操作符先输出。最后将当前操作符压入栈中。表达式扫描结束将操作符栈中剩余的所有操作符依次弹出并加入输出队列。输出队列中的元素顺序即为后缀表达式。优先级定义常规*,/优先级 2,-优先级 1左括号(在栈内时优先级特殊通常视为最低0以阻止其被弹出。完整示例将中缀表达式 “3 5 * (2 - 8) / 4” 转换为后缀表达式。我们一步步模拟这个过程扫描元素操作符栈 (栈顶在右)输出队列说明3[][3]数字直接输出[][3]栈空入栈5[][3, 5]数字直接输出*[, *][3, 5]*优先级高于栈顶直接入栈([, *, (][3, 5]左括号直接入栈2[, *, (][3, 5, 2]数字直接输出-[, *, (, -][3, 5, 2]栈顶是(-直接入栈8[, *, (, -][3, 5, 2, 8]数字直接输出)[, *][3, 5, 2, 8, -]遇到)弹出栈顶至(输出-丢弃(/[, /][3, 5, 2, 8, -, *]/优先级等于栈顶*弹出*输出/入栈4[, /][3, 5, 2, 8, -, *, 4]数字直接输出结束[][3, 5, 2, 8, -, *, 4, /, ]弹出栈中剩余/和输出最终得到的后缀表达式为3 5 2 8 - * 4 / 实操心得在实现调度场算法时处理操作符优先级比较的逻辑是重中之重。一个常见的技巧是定义一个precedence函数来返回操作符的优先级数值。另外要特别注意左括号的处理它入栈后优先级暂时失效直到遇到右括号才被激活。在比较优先级时一定要先判断栈顶是否是左括号。4. 代码实现与边界处理理解了算法我们来看具体的代码实现。这里以 Python 为例因为它语法清晰易于理解。我们将实现两个核心函数infix_to_postfix中缀转后缀和eval_postfix后缀表达式求值。4.1 中缀转后缀实现def infix_to_postfix(infix_expr): 将中缀表达式字符串转换为后缀表达式列表。 假设输入表达式 tokens 由空格分隔操作符为 - * /操作数为整数。 # 定义优先级字典 precedence {: 1, -: 1, *: 2, /: 2} # 使用列表模拟栈和输出队列 op_stack [] output [] # 分割表达式假设 tokens 用空格分开简化处理 # 实际中可能需要更复杂的词法分析器来处理连续的数字和符号 tokens infix_expr.split() for token in tokens: if token.isdigit(): # 如果是操作数这里简化处理整数 output.append(token) elif token (: op_stack.append(token) elif token ): # 弹出直到遇到左括号 while op_stack and op_stack[-1] ! (: output.append(op_stack.pop()) op_stack.pop() # 弹出左括号丢弃 elif token in precedence: # 如果是操作符 # 关键当栈非空栈顶不是左括号且当前操作符优先级 栈顶优先级时 while (op_stack and op_stack[-1] ! ( and precedence[token] precedence.get(op_stack[-1], 0)): output.append(op_stack.pop()) op_stack.append(token) else: raise ValueError(fInvalid token: {token}) # 将栈中剩余操作符全部弹出 while op_stack: output.append(op_stack.pop()) return .join(output) # 返回空格分隔的字符串 # 测试 infix 3 5 * ( 2 - 8 ) / 4 postfix infix_to_postfix(infix) print(f中缀表达式: {infix}) print(f后缀表达式: {postfix}) # 输出: 3 5 2 8 - * 4 / 代码关键点解析分词我们假设输入表达式由空格分隔这简化了问题。在实际的计算器或编译器中需要一个词法分析器来正确识别多位数、小数、变量名和操作符。优先级比较while循环的条件precedence[token] precedence.get(op_stack[-1], 0)是算法的核心。确保了相同优先级的操作符如和-遵循左结合律即左边的先计算。栈的使用Python 列表的append()和pop()方法完美模拟了栈的压入和弹出操作op_stack[-1]用于查看栈顶元素而不弹出。4.2 后缀表达式求值实现def eval_postfix(postfix_expr): 计算后缀表达式的值。 假设输入是空格分隔的字符串操作数为整数。 stack [] tokens postfix_expr.split() for token in tokens: if token.isdigit(): stack.append(int(token)) else: # 是操作符 # 弹出两个操作数注意顺序 right_operand stack.pop() left_operand stack.pop() if token : result left_operand right_operand elif token -: result left_operand - right_operand elif token *: result left_operand * right_operand elif token /: # 注意除零错误和整数除法 if right_operand 0: raise ZeroDivisionError(Division by zero) result left_operand / right_operand # Python 3 中为浮点除法 else: raise ValueError(fUnknown operator: {token}) stack.append(result) if len(stack) ! 1: raise ValueError(Invalid postfix expression) return stack[0] # 测试 postfix 3 5 2 8 - * 4 / result eval_postfix(postfix) print(f后缀表达式 {postfix} 的计算结果是: {result}) # 输出: -3.0求值过程的关键细节操作数顺序right_operand stack.pop()先执行left_operand stack.pop()后执行。这是因为栈是后进先出对于表达式A B -扫描时 B 先入栈A 后入栈所以栈顶是 B右操作数次顶是 A左操作数。这个顺序对于减法和除法至关重要。错误处理函数最后检查栈中是否只剩下一个元素如果不是说明表达式不合法例如操作符和操作数数量不匹配。同时除法运算中加入了除零检查。数据类型我们这里将操作数转换为int进行计算。实际应用中可能需要支持浮点数这时可以用float()转换或者根据词法分析的结果决定。注意事项这个示例为了清晰做了大量简化。一个健壮的表达式求值器还需要处理负数一元运算符、多位数字和小数、函数调用如sin,pow、变量赋值与求值等。这些都会让词法分析和语法分析变得复杂但其核心思想——使用栈来管理运算顺序——是不变的。5. 常见问题与实战避坑指南在实际编码和面试中围绕表达式转换与求值会遇到各种各样的问题。下面我整理了一些典型场景和容易踩的坑。5.1 如何处理无空格或复杂的表达式我们的示例代码要求表达式用空格分隔。但用户输入通常是35*(2-8)/4这样的连续字符串。处理这种情况需要词法分析。简易词法分析器思路def tokenize(expr): 一个简单的词法分析器将连续字符串分割成 token 列表。 tokens [] i 0 n len(expr) while i n: if expr[i].isspace(): # 跳过空格 i 1 elif expr[i].isdigit(): # 处理数字包括多位数和小数 j i while j n and (expr[j].isdigit() or expr[j] .): j 1 tokens.append(expr[i:j]) i j elif expr[i] in -*/(): # 处理操作符和括号 tokens.append(expr[i]) i 1 else: raise ValueError(fUnexpected character: {expr[i]}) return tokens # 使用 infix_expr 35*(2-8)/4 tokens tokenize(infix_expr) # 得到 [3, , 5, *, (, 2, -, 8, ), /, 4] # 然后将 tokens 列表传入修改后的 infix_to_postfix 函数将infix_to_postfix函数改为接收tokens列表而非分割字符串即可处理无空格表达式。5.2 如何支持更多运算符如指数^和函数扩展优先级只需在precedence字典中加入新操作符及其优先级。例如指数运算通常右结合且优先级最高precedence {:1, -:1, *:2, /:2, ^:3}在调度场算法中对于右结合的操作符如^比较条件需要从改为以确保连续的2^3^2被正确计算为2^(3^2)。支持函数函数名如sin,log可以视为一种特殊的操作符。在词法分析阶段识别出它们并赋予一个标识如FUNC。在转换时函数名直接压入操作符栈。当从栈中弹出时它需要一个操作数一元函数或多个操作数。5.3 求值时的整数与浮点数除法在 Python 3 中/是浮点除法//是整数除法。在实现计算器时需要明确使用哪种。一种常见的做法是如果两个操作数都是整数且能整除则返回整数否则返回浮点数。或者根据用户输入或模式设置来决定。5.4 面试高频考点与思路实现一个简单的计算器这几乎是必考题。核心就是中缀转后缀再求值。面试官可能会要求直接处理字符串s实现calculate(s)函数。你需要现场写出调度场算法和求值逻辑。处理负数一元运算符表达式如-53或3*(-2)。一元负号-和二元减号-在词法分析时难以区分。常见技巧是如果-出现在表达式开头或前一个 token 是(或另一个操作符则它是一元负号。可以将一元负号替换为一个特殊的操作符如~并赋予较高优先级在求值时执行取反操作。表达式合法性校验如何判断一个中缀表达式是否合法可以利用栈括号必须匹配。操作数数量比操作符数量多一个不考虑一元运算符。不能出现两个连续的操作符一元负号除外。扫描结束后操作符栈应为空除了可能的一元操作符。空间与时间复杂度调度场算法和后缀求值算法的时间复杂度都是O(n)其中 n 是表达式 token 的数量。空间复杂度也是O(n)主要用于栈和输出队列。5.5 一个综合案例带变量的表达式求值假设我们要处理x 10; y x 2 * 3;这样的语句。这需要引入符号表一个字典来存储变量的值。词法分析识别出变量名如x,y、数字、操作符和赋值号。语法分析对于赋值语句var expr先计算右侧表达式expr的值可能需要用到符号表中已有的变量值然后将结果存入符号表键为var。求值在后缀表达式求值过程中遇到变量 token不是压入数字而是从符号表中查找其值并压栈。这实际上已经是一个微型解释器的雏形将表达式处理提升到了一个新的层次。6. 从理论到应用表达式求值的广阔天地掌握了前缀、中缀、后缀表达式的原理和转换其意义远不止于解几道算法题。它是计算机科学中一个基础而强大的范式在众多领域有着深刻的应用。1. 编译器与解释器的核心这是表达式求值最经典的应用场景。无论是 C 语言编译器将a b * c编译成机器码还是 Python 解释器执行同一行代码其前端语法分析都会经历类似调度场算法的过程生成一种中间表示常常是抽象语法树其遍历序列就对应着前缀或后缀表达式后端再基于此生成代码或直接求值。理解这部分内容是打开编译原理大门的第一把钥匙。2. 软件计算器与数学工具所有科学计算器软件如 Windows 计算器、MATLAB、Mathematica以及 Excel 等电子表格软件的公式引擎其底层必然包含一个健壮的表达式解析与求值模块。它们需要处理远比我们示例复杂的表达式包括函数sin, cos, log、常量π, e、括号嵌套、运算符优先级和结合性等。你亲手实现的这个简易版正是这些强大工具的微观缩影。3. 领域特定语言与配置文件解析许多软件允许用户使用一种简化的表达式语言来配置规则或进行计算。例如监控系统的告警规则cpu_usage 90 memory_usage 80游戏中的技能伤害公式base_damage * (1 strength/100)或者图形化编程中的表达式节点。这些 DSL 的解释器其核心往往就是一个增强版的表达式求值器。4. 数据库查询优化在 SQL 查询中WHERE子句的条件表达式如age 18 AND (city ‘Beijing’ OR city ‘Shanghai’)在数据库内部也会被解析成一种可计算的中间形式。优化器可能会对条件进行重排或转换以寻求更高效的执行计划这个过程也涉及对表达式逻辑的分析和重构。5. 算法面试的常青树正如前文所述实现一个计算器LeetCode 上有 224. 基本计算器、227. 基本计算器 II 等题目是检验候选人栈应用、字符串处理、边界条件考虑能力的绝佳考题。它综合了数据结构、算法和编程基本功能够清晰地区分候选人的代码能力层级。我个人在实现和教学中的体会是表达式求值是一个“麻雀虽小五脏俱全”的完美教学案例。它用一个相对较小的问题串联起了栈的应用、算法设计、字符串处理、优先级处理、递归思想递归下降法也是实现表达式解析的另一种重要方法等多个核心知识点。当你能够不参考任何资料从零开始写出一个能处理带括号和加减乘除的表达式求值程序时你对栈的理解、对程序逻辑的控制能力会上一个坚实的台阶。这不仅仅是解决了一个具体问题更是获得了一种将复杂计算逻辑分解为确定步骤的思维工具。

相关新闻

BCD编码:从金融计算到嵌入式系统的精确十进制解决方案

BCD编码:从金融计算到嵌入式系统的精确十进制解决方案

1. 从“数字”到“数字”:BCD编码的诞生背景我们每天都在和数字打交道,无论是手机上的时间、超市里的价格标签,还是银行账户的余额。在计算机的世界里,这些数字最终都要被转换成二进制(0和1)才能被处理和存…

2026/10/7 5:40:02 阅读更多 →
京东自动化脚本终极指南:告别手动操作,轻松获取京豆

京东自动化脚本终极指南:告别手动操作,轻松获取京豆

京东自动化脚本终极指南:告别手动操作,轻松获取京豆 【免费下载链接】jd_scripts-lxk0301 长期活动,自用为主 | 低调使用,请勿到处宣传 | 备份lxk0301的源码仓库 项目地址: https://gitcode.com/gh_mirrors/jd/jd_scripts-lxk03…

2026/10/13 10:51:05 阅读更多 →
微波遥感数据重映射与雨水污染剔除:提升飓风暖芯反演精度的关键技术

微波遥感数据重映射与雨水污染剔除:提升飓风暖芯反演精度的关键技术

1. 项目概述:从“看见”到“看清”飓风内核在气象卫星遥感领域,尤其是针对飓风、台风这类极端天气系统的监测,我们一直在追求一个目标:如何穿透厚重的云墙和雨带,清晰地“看见”风暴最核心的结构——也就是所谓的“暖芯…

2026/10/6 10:57:32 阅读更多 →

最新新闻

低功耗WiFi MCU技术拆解:从蓝牙到WiFi SoC的迁移实战

低功耗WiFi MCU技术拆解:从蓝牙到WiFi SoC的迁移实战

最近圈子里有个动作挺值得关注,一家在蓝牙芯片领域站稳了脚跟的头部厂商,突然把产品线往WiFi SOC方向大力伸展,正式发布了自己的低功耗WiFi MCU系列。做了这么多年IoT开发,我见过太多“跨界”产品,大多数只是原有方案的…

2026/10/14 14:28:43 阅读更多 →
Traffic_parse:基于eBPF的网络流量语义解析系统

Traffic_parse:基于eBPF的网络流量语义解析系统

1. 项目概述:这不是抓包工具,而是一套“网络流量的显微镜”“Traffic_parse 流量特征解析项目”——光看名字,很多人第一反应是“又一个Wireshark插件”或者“tcpdump的高级封装”。但实际动手做过几轮真实业务场景的流量分析后,我…

2026/10/14 14:28:43 阅读更多 →
OpenCV4.9.0 GPU版VS2019编译实战:CUDA加速与避坑指南

OpenCV4.9.0 GPU版VS2019编译实战:CUDA加速与避坑指南

简介:这是一份基于Visual Studio 2019编译的OpenCV4.9.0 GPU release版资源,面向Windows平台C开发者,专为需要GPU并行加速的计算机视觉与图像处理场景设计。借助图形处理单元的并行计算能力,可显著提升高分辨率图像、实时视频流及…

2026/10/14 14:28:43 阅读更多 →
MiniMax H3视频工作室落地实战:部署、提速与国产卡适配

MiniMax H3视频工作室落地实战:部署、提速与国产卡适配

做AI视频落地的同行应该都有过这种经历:论文里的模型看着惊艳,真到自己机器上部署,从依赖冲突、显存爆掉到生成结果完全不是那么回事,每一步都可能劝退。这两年多模态视频生成模型迭代太快,开源社区也出了不少&#xf…

2026/10/14 14:28:43 阅读更多 →
Git核心命令实操总结:提交、撤回、分支与恢复避坑指南

Git核心命令实操总结:提交、撤回、分支与恢复避坑指南

接手一个陌生项目,大多数人下意识的操作就是git clone,这个命令敲了无数遍,闭着眼都能打出来。但真正进到日常开发会发现,好多人对 Git 的认知就停留在 clone、add、commit、push 四个命令上,一旦遇到撤回提交、处理冲…

2026/10/14 14:28:43 阅读更多 →
跨界资源整合:内容与资本的战略合作模式

跨界资源整合:内容与资本的战略合作模式

1. 战略合作背景解析启明社与安盛投资的这次战略合作,本质上是一次典型的跨界资源整合案例。启明社作为内容创作领域的头部机构,拥有强大的IP孵化能力和粉丝基础;而安盛投资则是金融投资领域的专业机构,在资本运作和商业资源方面具…

2026/10/14 14:27:40 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29: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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →