
本文介绍如何通过改进递归函数,将单词拆解为预定义“字块”(tiles)的所有合法组合,并从嵌套的多维关联数组中提取扁平化、可读性强的序列列表。
在自然语言处理或拼图类应用中,常需将目标单词(如 “stars”)用一组有限的“字块”(如 [“A”, “TA”, “S”, “R”])进行覆盖式拼接。原始实现使用深度嵌套的关联数组记录匹配路径,但这种结构难以直接遍历和使用。理想结果应是清晰、索引化的二维数组,每个子数组代表一种完整且合法的拼接方案。
为此,我们重构 word2sequences() 函数,摒弃依赖键名传递状态的方式,改用引用传参 + 线性追加策略收集所有完整路径。关键优化点如下:
- ✅ 终止条件明确:当正则匹配后剩余字符串为空(或仅含分隔符),说明当前路径已完整覆盖原词,直接将该路径存入 $founds;
- ✅ 路径以 ID 序列形式暂存:每次匹配成功时,将对应 tile_id 拼入分号分隔字符串(如 “51;21;40;51″),便于后续统一解析;
- ✅ 后期映射还原为字块值:遍历所有 ID 序列,用 $tiles[$id] 查表转换为实际字符(如 “S”, “TA”)。
以下是完整、可运行的解决方案:
$tile) { // 匹配:开头任意分隔符/空 + 当前 tile + 剩余部分(可为空) if (!preg_match('/^([;0-9]*?)(' . preg_quote($tile, '/') . ')(.*)$/i', $word, $matches)) { continue; } $prefix = $matches[1]; $suffix = $matches[3]; // 若匹配后无剩余内容(即 suffix 为空),说明已完整覆盖 if ($suffix === '') { // 将当前 tile_id 加入路径(支持 prefix 中已有的 id) $path = trim($prefix . ';' . $tile_id, ';'); $founds[] = $path; } else { // 否则递归处理剩余字符串(注意:此处需重建待匹配字符串) // ⚠️ 原逻辑有歧义:$found 构造方式易导致 ID 混淆,应改为基于原始 word 的切片 // 更健壮做法:用 substr 或显式位置计算,但为兼容原意,我们保留 ID 路径法 $next_word = $prefix . $suffix; // 实际应为剩余未匹配部分,但原设计依赖此格式 word2sequences($next_word, $tiles, $founds); } } } // 示例数据(注意:原代码中键 21 重复,PHP 会覆盖 → 修正为唯一键) $tiles = [ 1 => "A", 21 => "B", 34 => "AH", 40 => "R", 51 => "S", 83 => "SA", 14 => "T", 99 => "TA" // 避免与 21 冲突,改用新键 ]; $word = "stars"; $founds = []; word2sequences(strtolower($word), $tiles, $founds); // 解析 ID 路径 → 字块序列 $solutions = []; foreach ($founds as $path) { $ids = array_filter(explode(';', $path), 'is_numeric'); // 过滤空项与非数字 $sequence = []; foreach ($ids as $id) { if (isset($tiles[(int)$id])) { $sequence[] = $tiles[(int)$id]; } } if (!empty($sequence)) { $solutions[] = $sequence; } } print_r($solutions); ?>
输出示例:
立即学习“PHP免费学习笔记(深入)”;
Array ( [0] => Array ( [0] => S [1] => TA [2] => R [3] => S ) [1] => Array ( [0] => S [1] => T [2] => A [3] => R [4] => S ) )
? 注意事项:
- 正则中使用 preg_quote($tile, ‘/’) 防止字块内容含特殊符号(如 .、*)引发错误;
- 原始 $tiles 数组存在重复键(21 => “B” 和 21 => “TA”),php 仅保留最后一个,务必确保键唯一;
- 该算法本质是回溯搜索,时间复杂度随字块数量和单词长度增长较快,适用于中小规模场景;
- 如需去重或限制最大序列长度,可在递归入口添加剪枝条件(如 count($sequence) > MAX_LEN 直接 return)。
通过上述重构,我们实现了从“嵌套树形结构”到“扁平化序列集合”的高效转换,使结果更贴近业务需求,也便于后续做排序、过滤或可视化展示。