14

根据 wiki,最长的公共子串问题可以使用后缀树来解决。
来自维基

一组字符串的最长公共子串可以通过为字符串构建一个广义后缀树,然后从它下面的子树中的所有字符串中找到具有叶节点的最深内部节点来找到

我不明白这个。
示例:如果我有:
ABCDE然后XABCZ
后缀树是(XABCZ由于空格而省略了一些分支):
在此处输入图像描述

最长的公共子字符串是ABC,但它不是我看不到 wiki 的描述在这里有什么帮助。
ABC不是具有叶节点的最深内部节点。
任何帮助理解这是如何工作的?

4

2 回答 2

8

就像之前所说的,你的树是不正确的。

这就是通过我的代码运行“ABCDE$XABCZ”时得到的结果。

后缀树代码

String = ABCDE$XABCZ$
End of word character 1 = $
└── (0)
    ├── (20) $
    ├── (22) ABC
    │   ├── (15) DE$
    │   └── (23) Z$
    ├── (24) BC
    │   ├── (16) DE$
    │   └── (25) Z$
    ├── (26) C
    │   ├── (17) DE$
    │   └── (27) Z$
    ├── (18) DE$
    ├── (19) E$
    ├── (21) XABCZ$
    └── (28) Z$

在(紧凑)后缀树中,您需要从所有字符串中找到具有叶节点的最深内部节点。如果在同一深度有多个节点,则必须比较该节点表示的字符串的长度。即ABC、BC、C都有相同的深度,所以要比较ABC、BC、C字符串的长度,看哪个更长;这显然是ABC。

后缀特里代码

└── null
    ├── A
    │   └── B
    │       └── C
    │           ├── D
    │           │   └── (E) ABCDE
    │           └── (Z) ABCZ
    ├── B
    │   └── C
    │       ├── D
    │       │   └── (E) BCDE
    │       └── (Z) BCZ
    ├── C
    │   ├── D
    │   │   └── (E) CDE
    │   └── (Z) CZ
    ├── D
    │   └── (E) DE
    ├── (E) E
    ├── X
    │   └── A
    │       └── B
    │           └── C
    │               └── (Z) XABCZ
    └── (Z) Z

在(不紧凑的)后缀树中,从所有字符串中找到最深的内部节点,这些节点具有叶节点。

希望能帮助到你。

于 2012-06-12T21:16:57.937 回答
4

您实际上还没有绘制后缀树。如果你做得正确,从根本上你只会拥有每个可能的角色一次。仅当单个字母可以具有多个后续后缀时,树才会分裂。这迫使公共子串在树中聚集在一起,这使得它们可以被找到。

于 2012-06-12T20:28:04.157 回答