trie图的构建、活用与改进.docx

  1. 1、本文档共7页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Trie图的构建、活用与改进 我们知道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”。【样例输入】1rob1internetproblemsolvingcontest【样例输出】Yes【备注】因本题只是用来讨论trie图的构建方法,故未给出数据范围。【分析】判断文本是否包含不良单词可以一行一行地判断。而判断长为L的一行文本s是否含有不良单词可以这样进行:让i从1变化到L,依次判断s的前i个字符构成的字符串是否以不良单词结尾。然而,我们希望在判断s的前k个字符时,能够利用前k-1个字符的结果,即这两个状态间可以方便地进行转移。注意到trie树中的边正如一个个“方向标”,因此我们有了一个美好的设想:从根结点出发,沿着标有s[1]的边走一步,再沿标有s[2]的边走一步,一直这样走下去!现在有了一个问题:如果从当前走到的结点出发,没有需要走的边,该怎么办?只要“创造”一条这样的边即可。那么这条边应该指向哪个结点呢?如果同样“创造”一个结点,那是毫无意义的。解决这个问题,要从我们“沿边走”的动机谈起。我们之所以“沿边走”,是因为我们把结点看成了状态,把边看成了状态间转移的途径。要确定新加的边应连到哪个结点,就需要找我们想走到但去不存在的那个结点与已有的哪个结点是等价的。那么“等价”的标准是什么呢?我们先来解决另一个问题:定义trie树中从根结点到某个结点的路径上的边上的字符连起来形成的字符串为这个结点的路径字符串。如果一个结点的路径字符串以不良单词结尾,那么称这个结点为危险结点,否则称之为安全结点。那么如何判断某个结点是否危险呢?显然根结点是安全结点。对于一个非根结点,它是危险结点的充要条件是:它的路径字符串本身就是一个不良单词,或者它的路径字符串的后缀(一个字符串去掉第一个字符后剩下的部分叫做它的后缀)对应的结点(一个字符串对应的结点是指在trie图中从根出发,依次沿该字符串的每个字符走一步所达到的结点)是危险结点。如果称一个结点的路径字符串的后缀对应的结点为它的后缀结点,那么如何求任一结点的后缀结点呢?根结点的后缀结点是它本身。处于trie树第二层的结点的后缀结点也是根结点。对于再往下的某个结点,设它的路径字符串的最后一个字符为c,那么这个结点的后缀为从它在trie树中父结点的后缀结点出发,沿标有c的边走一步后到达的结点。(下文中称从x结点出发,沿标有字符c的边走一步到达的结点为x的c孩子)那么,如果它的父结点的后缀结点w没有c孩子怎么办呢?到此,我们看到两个问题已经合而为一了。我们假设w有这样一个c孩子(记作x),并且从x出发又繁衍出无数的子子孙孙。我们来判断以x为根的子树中的结点的危险性。显然x本身的路径字符串不是不良单词,且它的子孙的路径字符串也不是不良单词。因此以x为根的子树中任一结点y的危险性与y的后缀结点的危险性相同(回忆一下一个非根结点是危险结点的充要条件)。这也就是说,以x为根的子树与以x的后缀结点为根的子树是一模一样的。因此,我们把需要新建的从w指向x的边直接指向x的后缀结点,即w结点的后缀结点的c孩子即可。简言之,由于x本身的路径字符串既不是不良单词,又不是某个不良单词开头的一部分,所以它的首字母便没有用了!在这种情况下,x结点就等价于它的后缀结点。由此我们可以把trie树改造成一个有向图:按层次遍历trie树,求出每个结点的危险性和后缀结点,并补齐由它出发的边。危险性与后缀结点的求法在【分

文档评论(0)

管理学科 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档