使用字典,BFS 是最佳的,但所需的运行时间与其大小(V+E)成正比。对于 n 个字母,字典可能有 ~a^n 个整数,其中 a 是字母大小。如果字典包含所有单词,但应该在链末尾的单词除外,那么您将遍历所有可能的单词但不会找到任何东西。这是图遍历,但大小可能呈指数级增长。
您可能想知道是否有可能更快地做到这一点——“智能地”浏览结构并在多项式时间内完成。答案是,我认为,不。
问题:
你有一个快速(线性)的方法来检查一个单词是否在字典中,两个单词 u, v 并检查是否有一个序列 u -> a 1 -> a 2 -> ... -> a n ->诉。
是 NP 难的。
证明:以一些 3SAT 实例为例,例如
(p or q or not r) and (p or not q or r)
您将从 0 000 00 开始,并检查是否可以转到 2 222 22。
第一个字符将是“我们完成了吗”,接下来的三个位将控制 p、q、r,而接下来的两个位将控制子句。
允许的词是:
- 任何以 0 开头且仅包含 0 和 1 的内容
- 任何以 2 开头且合法的内容。这意味着它由 0 和 1 组成(除了第一个字符是 2 之外,所有子句位都根据变量位正确设置,并且它们设置为 1(因此这表明公式是可满足的)。
- 以至少两个 2 开头然后由 0 和 1 组成的任何内容(正则表达式:222* (0+1)*,如 22221101 但不是 2212001
要从 0 000 00 产生 2 222 22,您必须这样做:
(1) 翻转适当的位 - 例如分四步翻转 0 100 111。这需要找到 3SAT 解决方案。
(2) 将第一位更改为 2:2 100 111。在这里您将得到验证,这确实是一个 3SAT 解决方案。
(3) 改变 2 100 111 -> 2 200 111 -> 2 220 111 -> 2 222 111 -> 2 222 211 -> 2 222 221 -> 2 222 222。
这些规则强制您不能作弊(检查)。只有当公式是可满足的并且检查是 NP-hard 时,才可能转到 2 222 22。我觉得它可能更难(可能是#P 或 FNP),但我认为 NP 硬度足以达到这个目的。
编辑:您可能对不相交集数据结构感兴趣。这将获取您的字典和可以相互访问的组词。您还可以存储从每个顶点到根或其他顶点的路径。这会给你一条路径,不一定是最短的。