资讯详情

资讯详情

freeCodeCamp 每日编码挑战实战:用 Python 实现罗马数字解析器(Roman Numeral Parser)

freeCodeCamp 每日编码挑战实战用 Python 实现罗马数字解析器Roman Numeral Parser【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp本篇文章以 freeCodeCamp 开源仓库中的每日编码挑战Challenge 28: Roman Numeral Parser位于curriculum/challenges/english/blocks/daily-coding-challenges-python/68adce01c0e1144d0a90295c.md为讲解主体完整还原题目要求、符号映射表、减法规则与全部 7 个自动化测试用例并逐行拆解官方参考解法。读完本文后你将掌握「从左到右扫描 前后值比较」这一罗马数字解析核心算法理解 freeCodeCamp 挑战中runPython测试的运行方式并了解仓库中支撑每日挑战的前后端基础设施。一、挑战背景freeCodeCamp 的每日编码挑战Python在 freeCodeCamp 课程体系中daily-coding-challenges-python是一个独立的挑战块block它收纳了 200 余道按编号排列的 Python 小挑战。本挑战的元数据位于仓库的 daily-coding-challenges-python 块定义块名称daily-coding-challenges-python标记isUpcomingChange: true属于即将上线的新内容编辑器usesMultifileEditor: true帮助分类helpCategory: Python布局blockLayout: legacy-challenge-list在该块的challengeOrder中本挑战的编号与 ID 被定义为{ id: 68adce01c0e1144d0a90295c, title: Challenge 28: Roman Numeral Parser }仓库还通过 每日挑战一致性测试 确保 JavaScript 版与 Python 版的每日挑战一一对应两套挑战数量必须相等且每个挑战的id、title、description与测试用例数量必须完全一致。这意味着你在学习 Python 解法时可以随时对照同主题的 JavaScript 版本强化对同一算法的多语言理解。二、题目要求与函数签名原文档给出的题目描述非常简洁Given a string representing a Roman numeral, return its integer value.给定一个表示罗马数字的字符串返回其整数值。你需要实现一个名为parse_roman_numeral的函数接收一个罗马数字字符串numeral返回对应的十进制整数。挑战附带的初始种子代码seed如下def parse_roman_numeral(numeral): return numeral可以看到种子代码只给出了函数骨架甚至默认return numeral直接返回原字符串——所有逻辑都需要你自行补全。三、符号映射表与核心规则原文档给出了罗马数字的基础符号与数值对照表这是整个解题过程的地基Symbol符号Value数值I1V5X10L50C100D500M1000仅凭符号表还不足以解析任意罗马数字原文档补充了唯一的、也是最关键的一条规则Numerals are read left to right. If a smaller numeral appears before a larger one, the value is subtracted. Otherwise, values are added.数字从左到右读取。如果较小的数字出现在较大的数字之前则将其值减去否则将其值相加。这条规则可以拆解为两点顺序加法当当前符号的值不小于下一个符号的值时直接把当前值累加到总和上。逆序减法当当前符号的值小于下一个符号的值时说明出现类似IV4、IX9这样的减性组合此时应把当前值从总和中减去。例如IVI1出现在V5之前1 5所以结果是5 - 1 4。而VIV5大于I1正常相加得5 1 6。四、7 个自动化测试用例逐一剖析原文档通过runPython内嵌unittest.TestCase().assertEqual(...)的方式提供了 7 个测试用例。这些用例覆盖了从最简单到稍复杂的多种情况是验证解法正确性的唯一标准。下面逐一说明每个用例考查的能力点1. 纯加法parse_roman_numeral(III)应返回3({test: () { runPython( from unittest import TestCase TestCase().assertEqual(parse_roman_numeral(III), 3)) }})三个连续的I全部按加法累加1 1 1 3。这是最简单的用例验证基础遍历与累加逻辑。2. 减法组合parse_roman_numeral(IV)应返回4({test: () { runPython( from unittest import TestCase TestCase().assertEqual(parse_roman_numeral(IV), 4)) }})I1小于后一位V5触发减法5 - 1 4。这是对「较小数字在前则相减」规则的直接检验。3. 混合加减parse_roman_numeral(XXVI)应返回26({test: () { runPython( from unittest import TestCase TestCase().assertEqual(parse_roman_numeral(XXVI), 26)) }})X X V I 10 10 5 1 26。整个过程没有任何相邻逆序全部相加。4. 双重减法parse_roman_numeral(XCIX)应返回99({test: () { runPython( from unittest import TestCase TestCase().assertEqual(parse_roman_numeral(XCIX), 99)) }})XCX10小于C100减法得100 - 10 90IXI1小于X10再减一次得90 (10 - 1) 99。该用例验证算法能否在一条罗马数字中连续处理多处减法组合。5. 减法嵌套在中间parse_roman_numeral(CDLX)应返回460({test: () { runPython( from unittest import TestCase TestCase().assertEqual(parse_roman_numeral(CDLX), 460)) }})CDC100小于D500减法得400接着L50、X10顺序递减全部相加400 50 10 460。该用例验证「减性组合出现在数字开头」的场景。6. 减法后跟加法parse_roman_numeral(DIV)应返回504({test: () { runPython( from unittest import TestCase TestCase().assertEqual(parse_roman_numeral(DIV), 504)) }})D500单独成立IV是减性组合500 (5 - 1) 504。注意I1与V5相比是减法但D500与I1之间隔着V并不直接比较——这恰好说明了逐位「只看相邻两位」的扫描策略是正确且高效的。7. 长串罗马数字parse_roman_numeral(MMXXV)应返回2025({test: () { runPython( from unittest import TestCase TestCase().assertEqual(parse_roman_numeral(MMXXV), 2025)) }})M M X X V 1000 1000 10 10 5 2025。长串纯加法验证循环能正确处理任意长度的输入。用例覆盖小结输入期望输出考查要点III3基础加法IV4单次减法XXVI26纯加法长串XCIX99连续两处减法CDLX460开头减法 后续加法DIV504加法与减法混合MMXXV2025长串加法千位级五、官方参考解法与逐行拆解原文档在# --solutions--一节给出了完整参考解法def parse_roman_numeral(numeral): roman_map { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 } total 0 for i in range(len(numeral)): current roman_map[numeral[i]] next_val roman_map[numeral[i 1]] if i 1 len(numeral) else 0 if current next_val: total - current else: total current return total下面逐段拆解其工作原理第一步建立符号映射表roman_map { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 }用 Python 字典把 7 个罗马符号映射到对应的十进制数值与题目给出的符号表完全一致。字典查表的时间复杂度为 O(1)这也是解析罗马数字的标准做法。第二步初始化累加器total 0total用于保存最终结果遍历过程中逐步累加或累减。第三步从左到右逐位扫描for i in range(len(numeral)): current roman_map[numeral[i]] next_val roman_map[numeral[i 1]] if i 1 len(numeral) else 0current当前字符对应的数值。next_val下一个字符对应的数值若当前已是最后一个字符i 1 len(numeral)则取0。取0的意义在于任何正数都不会小于0因此最后一个字符必然走「相加」分支保证循环安全收尾而无需单独处理边界。第四步比较前后值决定加还是减if current next_val: total - current else: total current这正是原文档规则「较小数字出现在较大数字之前则相减否则相加」的直接代码化表达。以XCIX为例走一遍索引currentnext_val比较操作total0X1010010 100减-101C10010100 10加902I1101 10减893X10010 0加99最终返回99与测试用例一致。这种「只看相邻两位」的贪心扫描策略正是经典罗马数字解析算法的精髓它把「减性组合」视为当前位少加了一次而非单独识别IV、IX这样的整体 token从而让代码保持极简。复杂度分析时间复杂度O(n)其中 n 为罗马数字字符串长度只需一次线性扫描空间复杂度O(1)除固定大小的映射字典外无额外空间开销。六、在 freeCodeCamp 环境中如何验证与运行原文档中的测试用例全部以runPython(...)的形式内嵌在挑战的--hints--区块中最终会转换为 Python 的unittest断言在浏览器内执行。仓库源码揭示了这套运行机制的实现细节浏览器端通过 python-worker-handler.ts 创建 Web Workernew Worker(pythonWorkerSrc)在其中加载 Pyodide 之类的 Python 运行时接收print、input、reset、stopped等事件消息实现浏览器内直接执行 Python 代码挑战的前端 UI 由 daily-coding-challenge 组件目录 提供包括widget.tsx挑战小部件、calendar.tsx日历视图等每日挑战数据从数据库取出后会经过 daily-coding-challenge-validator.ts 的 Joi Schema 校验其中明确要求每个挑战同时包含javascript与python两种语言的tests测试文本与testString和challengeFiles挑战文件内容与本挑战中 Python 测试用例 种子代码的结构一一对应。因此你在本地编辑器里写出函数后系统会拿 7 个TestCase().assertEqual(...)断言逐一运行全部通过才算完成挑战。七、边界情况与延伸思考原文档给出的测试覆盖了加减法的主流场景但在真实面试或工程场景中还可以进一步思考以下边界问题以下为罗马数字的通用常识供延伸练习参考非法字符若输入包含A、a等非罗马符号roman_map[numeral[i]]会抛出KeyError。若需要健壮性可提前校验或改用roman_map.get(char, 0)。无效排列如IIII、VX、IC这类不符合标准罗马数字书写规则的字符串上述算法会给出「算术上正确、书写上非法」的结果IIII→ 4IC→ 99。是否需要拒绝这类输入取决于题目是否要求校验格式。空字符串循环不会执行直接返回0。大小写标准罗马数字通常大写若需兼容小写输入可在入口处调用numeral.upper()。输出范围经典罗马数字一般只用于 13999 之间的整数超过 3999 需要引入带横线的扩展符号体系。需要说明的是当前这道挑战只要求「给定合法字符串返回整数值」并未要求校验输入合法性因此官方解法刻意保持了最精简的形态。八、总结Challenge 28: Roman Numeral Parser 是一道典型的「查表 线性扫描」入门级算法题核心数据结构7 元素的符号-数值字典O(1) 查表核心算法从左到右逐位扫描当前值小于后一位值则减、否则加一次遍历即可完成解析验证方式仓库通过runPythonunittest提供 7 个覆盖加法、减法、混合场景的断言用例并借助浏览器内 Python Worker 实时运行。掌握了这道题你不仅能独立完成 freeCodeCamp 的对应挑战也顺带掌握了处理「相邻符号决定正负」这类序列问题的通用思路——同样的模式可以迁移到计算器表达式求值、加减号压缩字符串等许多场景。仓库中同块的 Roman Numeral BuilderChallenge 123正是本挑战的逆运算完成「解析」后再挑战「生成」可以对罗马数字体系形成完整的认知闭环。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →