
本文介绍如何通过改进递归函数,将单词拆解为预定义“字块”(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)。
通过上述重构,我们实现了从“嵌套树形结构”到“扁平化序列集合”的高效转换,使结果更贴近业务需求,也便于后续做排序、过滤或可视化展示。











