Trie图的构建、活用与改进.pdfVIP

  • 3
  • 0
  • 约9.28千字
  • 约 7页
  • 2020-12-26 发布于浙江
  • 举报
2006 年全国信息学冬令营讲座 Trie 图的构建、活用与改进 Maigo 2006.1.14 我们知道 trie 树 (也叫字母树)这种数据结构。它是词典的一种存储方式。词典中的每 一个单词在 trie 树中表现为一条从根结点出发的路径,路径中边上的字母连起来就形成对应 的单词。图 1 就是一棵 trie 树,其中含有 a,abc,bac,bbc,ca 五个单词。 利用 trie 树可以对词典中的单词进行一些适合用树这种数据结构进行的操作,如求两个 单词的公共前缀长度(在树中表现为求两个单词对应结点的最近公共祖先)。其实,如果把 trie 树加以改造,多连一些边,形成的 trie 图在解决多模式串匹配问题上会发挥奇效。 左:图 1,一棵含有五个单词的trie 树。红色表示单词终止的位置。 右:图 2 ,由图 1 的trie 树改造成的 trie 图。红色表示危险结点,白色表示真安全结点, 蓝色表示新加的边。为简单起见,危险结点以下的结点及与之关联的边没有画出。 一、Trie 图的构建 我们通过一个例题来探究 trie 图的构建方法。 【例1】不良单词探测器 【题目描述】给出一个词典,其中的单词为不良单词。单词均为小写字母。再给出一段文本, 文本的每一行也由小写字母构成。判断文本中是否含有任何不良单词。例如,若 rob 是不良 单词,那么文本 problem 含有不良单词。 【输入】第一行为一个整数 n ,表示不良单词的个数。接下来n 行是词典。下面一行为一个 整数 m ,表示文本的行数。接下来m 行是文本。 【输出】如果文本包含不良单词,输出一行“Yes ”,否则输出一行“No ”。 【样例输入】 1 rob 1 internetproblemsolvingcontest 【样例输出】 Yes 【备注】因本题只是用来讨论trie 图的构建方法,故未给出数据范围。 【分析】判断文本是否包含不良单词可以一行一行地判断。而判断长为 L 的一行文本 s 是否 含有不良单词可以这样进行:让 i 从 1 变化到 L ,依次判断 s 的前 i 个字符构成的字符串是 否以不良单词结尾。 2006 年全国信息学冬令营讲座 然而,我们希望在判断 s 的前k 个字符时,能够利用前 k-1 个字符的结果,即这两个状 态间可以方便地进行转移。注意到 trie 树中的边正如一个个“方向标”,因此我们有了一个 美好的设想:从根结点出发,沿着标有 s[1]的边走一步,再沿标有 s[2]的边走一步,一直这 样走下去! 现在有了一个问题:如果从当前走到的结点出发,没有需要走的边,该怎么办?只要“创 造”一条这样的边即可。那么这条边应该指向哪个结点呢?如果同样“创造”一个结点,那 是毫无意义的。解决这个问题,要从我们“沿边走”的动机谈起。 我们之所以“沿边走”,是因为我们把结点看成了状态,把边看成了状态间转移的途径。 要确定新加的边应连到哪个结点,就需要找我们想走到但去不存在的那个结点与已有的哪个 结点是等价的。那么“等价”的标准是什么呢?我们先来解决另一个问题: 定义 trie 树中从根结点到某个结点的路径上的边上的字符连起来形成的字符串为这个 结点的路径字符串。如果一个结点的路径字符串以不良单词结尾,那么称这个结点为危险结 点,否则称之为安全结点。那么如何判断某个结点是否危险呢? 显然根结点是安全结点。对于一个非根结点,它是危险结点的充要条件是:它的路径字 符串本身就是一个不良单词,或者它的路径字符串的后缀(一个字符串去掉第一个字符后剩 下的部分叫做它的后缀)对应的结点(一个字符串对应的结点是指在 trie 图中从根出发,依 次沿该字符串的每个字符走一步所达到的结点)是危险结点。如果称一个结点的路径字符串 的后缀对应的结点为它的后缀结点,那么如何求任一结点的后缀结点呢? 根结点的后缀结点是它本身。处于 trie 树第二层的结点的后缀结点也是根结点。对于再 往下的某个结点,设它的路径字符串的最后一个字符为 c,那么这个结点的后缀为从它在trie 树中父结点的后缀结点出发,沿标有 c 的边走一步后到达的结点。(下文中称从x 结点出发, 沿标有字符 c 的边走一步到达的结点为x 的

文档评论(0)

1亿VIP精品文档

相关文档