- 示例工程
【免费下载链接】retos-programacion-2023
Ejercicios de código semanales en 2023 de la comunidad MoureDev para practicar lógica en cualquier lenguaje de programación.
导读
本文围绕 retos-programacion-2023 仓库中 Reto #1 - EL LENGUAJE HACKER 这道"Fácil(简单)"难度题目展开,完整讲解如何编写一个把自然语言文本转换为 leet(也称 1337 或"lenguaje hacker")的程序,并给出题目规定的 26 个字母与 10 个数字的标准映射表。通过阅读本文,你将掌握"查表 + 逐字符遍历 + 大小写归一化 + 未命中字符原样保留"这一通用算法骨架,并看到它在 Python、JavaScript、C、C#、Go、Rust、Kotlin、Bash、SQL(PostgreSQL/BigQuery)等 20 余种语言中的真实实现,可用于复现或提交你自己的解法。
题目原文与要求解析
题目原文(ejercicio.md)的核心要求如下:
编写一个程序,接收一段文本,将自然语言转换为"lenguaje hacker"(即 leet / 1337)。该语言的特点是替换字母数字字符。使用 leet 字母表(字母和数字)进行转换,且每次变换采用表中的第一种选项(例如用 "4" 表示 "a")。
题目为 2023 年第 1 周挑战,难度标注为 Fácil(简单),发布于 2023-01-02,官方纠错日期为 2023-01-09。从仓库规模看,该题吸引了社区大量贡献者:仅 Python 就有 276 份解法,JavaScript 160 份、Java 96 份、C# 36 份、TypeScript 36 份、Kotlin 33 份,覆盖 20 余种编程语言,非常适合作为跨语言算法对比的入门案例。
关键设计约束
从题目描述中可以提炼出三个必须满足的约束:
- 逐字符替换:对输入文本中的每个字母与数字执行替换,而不是对单词整体替换;
- 取映射表第一种选项:leet 同一种字母往往有多种写法,题目明确要求一律使用每种字母的第一种变换(例如 a → 4,而不是 @);
- 保留无关字符:空格、标点、非字母数字字符如何处理虽未明说,但从社区主流实现看均保留原样,以保证空格分隔与可读性。
标准 leet 映射表(题目规定的第一选项)
综合仓库中 Python、JavaScript、C#、Kotlin、Go、Rust、SQL 等实现的字典(可对照 miguelex.py 与 darubiano.sql),题目要求使用的完整映射如下:
| 原文 | leet | 原文 | leet | 原文 | leet |
|---|---|---|---|---|---|
| a | 4 | n | ^/ | 1 | L |
| b | I3 | o | 0 | 2 | R |
| c | p | |* | 3 | E | |
| d | ) | q | (_,) | 4 | A |
| e | 3 | r | I2 | 5 | S |
| f | |= | s | 5 | 6 | b |
| g | & | t | 7 | 7 | T |
| h | # | u | (_) | 8 | B |
| i | 1 | v | / | 9 | g |
| j | ,_| | w | // | 0 | o |
| k | >| | x | >< | ||
| l | 1 | y | j | ||
| m | //\ | z | 2 |
需要特别提醒的坑点:
- 大小写映射不一致:a→4、b→I3、e→3 是小写字母输出大写形式,而 i→1、l→1、o→0 又输出小写。因此实现时不能简单用"同一字符的大小写转换"来推导,必须照表逐条硬编码;
- 多字符输出:b、c、f、j、k、m、n、p、q、r、u、v、w 等字母的 leet 形态是 2~4 个字符组成的组合符号,如 w → //、m → //\、q → (_,);
- 数字映射:数字的 leet 形式多为对应大写/小写字母(1→L、2→R、3→E、4→A、5→S、6→b、7→T、8→B、9→g、0→o),注意 6 与 9 对应的是小写 b 与 g。
通用算法骨架:查表 + 逐字符遍历
尽管社区解法语言各异,但核心算法高度一致,可归纳为四步:
- 构建映射字典/表:以 26 个字母 + 10 个数字为键,leet 形式为值;
- 统一大小写:将输入转为小写(或查找时对字符做 lower 归一化),保证大写输入同样命中映射;
- 逐字符遍历:对每个字符查表,命中则拼接 leet 形式,未命中(空格、标点、重音字符如 ñ、@ 等)则保留原字符;
- 输出拼接结果。
以 Python 为例([miguelex.py 的HackerEncode函数):
def HackerEncode(plainText): leetCode = { 'a': '4', 'b': 'I3', 'c': '[', 'd': ')', 'e': '3', 'f': '|=', 'g': '&', 'h': '#', 'i': '1', 'j': ',_|', 'k': '>|', 'l': '1', 'm': '/\\/\\', 'n': '^/', 'o': '0', 'p': '|*', 'q': '(_,)', 'r': 'I2', 's': '5', 't': '7', 'u': '(_)', 'v': '\\/', 'w': '\\/\\/', 'x': '><', 'y': 'j', 'z': '2', '0': 'o', '1': 'L', '2': 'R', '3': 'E', '4': 'A', '5': 'S', '6': 'b', '7': 'T', '8': 'B', '9': 'g' } encryptedText = "" for letter in plainText: if letter.lower() in leetCode.keys(): encryptedText += leetCode[letter.lower()] else: encryptedText += letter.lower() return encryptedText print(HackerEncode("leet")) # 1337 print(HackerEncode("Mi nombre es Miguelex")) # /\/\1 n0/\/\13 35 /\/\19(_)1313>< print(HackerEncode("1234567890")) # LREASbTBgo print(HackerEncode("Hola Mundo!! Esto es una_prueba con caracteres extrañ@s"))注意代码中letter.lower()的双重作用:既作为字典键实现大小写归一,也保证了未命中字符(如空格、!、@、ñ、下划线)以小写形式原样保留。
运行验证(Go 版自带测试用例)
仓库中不少实现自带验证用例。例如 lombervid.go 的main函数内置了 5 组断言,直接运行go run lombervid.go即可看到每组的 pass/fail 结果:
| 输入 | 期望输出 | |
|---|---|---|
| demo | )3//\0 | |
| hacker | #4> | 3I2 |
| H4x0r | #A><oI2 | |
| Hello World! | #3110 //0I21)! | |
| My password is: 17o^DuQn$qNj | //\j |*455//0I2) 15: LT0^)()(,)^/$(,)^/,| |
其中Hello World!一行尤其值得注意:输入中的大写 H、W 被正确归一化为小写后命中映射,而空格与感叹号被原样保留,这正是"统一小写 + 未命中保留"策略的直接验证。Rust 版 [lombervid.rs 也提供了完全相同的 5 组断言。
多语言实现对比与要点
JavaScript / TypeScript
JavaScript 版(ACahuiche.js)同样使用对象作为映射表,利用for...of遍历字符串并做toLowerCase()归一化,未命中字符保留原样:
function leet(texto) { let alfabeto = { a: "4", b: "I3", /* ...全表... */ 0: "o" }; let traduccion = ""; for (let letra of texto.toLowerCase()) { traduccion += letra in alfabeto ? alfabeto[letra] : letra; } console.log(traduccion); } leet("Hola Hackers"); // #0l4 #4>|3I25TypeScript 版([RobTov.ts)在对象字面量外加了const leetCode: any类型标注,并把遍历改为split("")后forEach+includes判断,最后以export {}收尾,属于可被模块引用的写法。此外 html-js 目录下还有 Rdiaz97.html 这样的浏览器交互版本:它通过<input>输入框 + 按钮触发hacker()函数,用大量if/else if逐字符replace并document.write输出,适合在不引入构建工具的场景下快速演示。
C / C++
C 语言没有内置字典,kyrex23 的解法(kyrex23.c)用两个等长数组模拟映射:KEYS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"与按顺序排列的VALUES[]数组,通过toupper()归一化后线性查找下标。其注释明确写明了两个工程细节:
- 输出缓冲按
BUFFER_SIZE * 4分配,因为最长的 leet 形态(如 //)需要 4 个字符,避免拼接时缓冲区溢出; - 支持两种运行方式:
./kyrex23无参数时从 stdin 交互读取,./kyrex23 <your_string>则直接取第一个命令行参数作为输入。
C# / Kotlin / PHP
C# 版(miguelex.cs)使用Dictionary<string, string>,遍历时对char调用ToString().ToLower()作为键查询;Kotlin 版(miguelex.kt)与 Python 版结构几乎逐行对应;PHP 版(kodenook.php)则在函数签名上做了类型约束function leet(string|int $txt): string,先str_split((string)$txt)再逐字符拼接,同时以declare(strict_types=1);开启严格类型模式。
三者的共同模式是:用语言原生字典类型承载映射表,逐字符查表拼接。这也说明该题"数据结构选字典、控制流用遍历"的解法在命令式语言间几乎可无缝迁移。
Bash
Bash 版(alevil8022.sh)展示了无字典类型环境下如何实现:使用关联数组declare -A alfabeto存储映射,read -p提示输入,用${texto,,}转为全小写后写入临时文件,再通过cut -c按字符位置逐个截取并拼接。值得注意其映射表中alfabeto[0]='0'与社区主流的0→o不同,属于贡献者的个性化选择——这也从侧面说明,题目只规定了"字母的第一种变换",数字的变换在社区实现中存在细微差异。
SQL(PostgreSQL 与 BigQuery)
SQL 版(darubiano.sql)是一份非常完整的双引擎实现,演示了"用数据库函数做字符串转换"的思路:
- PostgreSQL 版:定义
pg_temp.LenguajeHacker(texto TEXT)临时函数,用 CTEdiccionario_hacker以VALUES列表构造 36 行字典,再用REGEXP_SPLIT_TO_TABLE(texto,'')把输入拆成单字符行,LEFT JOIN字典后STRING_AGG重新聚合,并以COALESCE保证未命中字符原样保留; - BigQuery 版:将字典改为
UNNEST([STRUCT('a' AS letra,'4' AS traduccion), ...])构造,配合SPLIT(texto,'')拆字符、LOWER()归一化后STRING_AGG聚合。
这份文件同时给出了两段可直接执行的完整脚本及示例调用SELECT * FROM pg_temp.LenguajeHacker('Aquí está un texto de prueba...'),是"用 SQL 解字符串算法题"的极佳参考,也印证了同一套映射表在关系模型下可以用"拆行 → 关联 → 聚合"三步等价实现。
边界情况与质量要点总结
综合社区实现与自带的测试断言,实现该题时建议关注以下边界:
- 大小写:输入通常混合大小写(如 "Hola Mundo"),必须做小写归一化后再查表,否则大写字符会全部漏匹配;
- 空格与标点:空格、!, @、_、重音字符(如 ñ)等不在表中,应原样保留,保证输出可读且不破坏分词;
- 缓冲区/类型安全:C 等静态语言要注意 leet 形态最长 4 字符导致输出变长,PHP 这类语言可用
string|int联合类型声明签名;C#/Java/Kotlin 直接拼接字符串即可; - 可验证性:参照 lombervid.go 的做法,为自己实现附加几组输入-期望输出断言,是最简单的自测方式。
深入阅读
- 题目说明:[Reto #1 - EL LENGUAJE HACKER [Fácil]/ejercicio.md](Retos/Reto #1 - EL LENGUAJE HACKER [Fácil]/ejercicio.md)
- Python 参考实现:python/miguelex.py
- Go 带测试用例实现:go/lombervid.go
- Rust 带测试用例实现:rust/lombervid.rs
- JavaScript 实现:javascript/ACahuiche.js
- TypeScript 实现:typescript/RobTov.ts
- C 实现(含命令行参数用法):c/kyrex23.c
- SQL(PostgreSQL + BigQuery)实现:sql/darubiano.sql
- 浏览器交互版:html-js/Rdiaz97.html
你可以在仓库对应语言目录下找到更多贡献者解法,选一种自己熟悉的语言动手实现,并与上述测试用例对照验证。
- 示例工程
【免费下载链接】retos-programacion-2023
Ejercicios de código semanales en 2023 de la comunidad MoureDev para practicar lógica en cualquier lenguaje de programación.
相关推荐
Mall4j Java 商城系统开源版全览:技术选型、多模块架构与快速启动指南
Mall4j Java 商城系统开源版全览:技术选型、多模块架构与快速启动指南 Mall4j 是一个面向企业电商平台建设的 Java 商城系统源码产品体系,本仓
示例工程retos-programacion-2023 第 33 题实战:用任意语言实现 Tetris 单方块位移与旋转
retos programacion 2023 第 33 题实战:用任意语言实现 Tetris 单方块位移与旋转 导读 本文以 MoureDev 社区 2023
示例工程从按键序列还原文字:MoureDev 编程挑战第 30 题 T9 键盘的多语言实现解析
从按键序列还原文字:MoureDev 编程挑战第 30 题 T9 键盘的多语言实现解析 本文以 MoureDev 社区 2023 每周编程挑战第 30 题「El
示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考