zoukankan      html  css  js  c++  java
  • 使用AC自动机解决文章匹配多个候选词问题

    解决的问题

    KMP算法用于单个字符串匹配,AC自动机用于文章中匹配多个候选词。

    注:本文所有图例见:AC自动机示例

    流程

    第一步,先将候选词先建立前缀树。

    第二步,以宽度优先遍历的方式把前缀树的每个节点设置fail指针, 头节点的fail指针指向空, 头节点孩子的fail指针指向头, 其他节点的fail指针设置逻辑为:来到X节点的时候,是设置X的孩子的fail指针。

    case 1:

    假设X通过b指向了它的孩子,假设孩子为C,X的fail指针指向的节点假设为Y,Y有走向b的路,且Y走向b的路是指向的Z,那么 C的fail指针指向Z,Y没有走向b的路,那么就看Y的fail指针指向的节点的fail指针有没有走向b的路,依次往复,如果走到null都没有,那么进入case 2

    case 2:

    如果X的fail指针指向null,那么就把X的孩子C指向头节点

    候选词构造AC自动机的一些示例,其中虚线表示节点fail指针的指向位置,黑色点表示候选词结尾位置。

    示例一 ["abc","bkf","abcd","bkc"]

    image

    示例二 ["abcde","cde","e"]

    image

    示例三 ["abcde","bcde","cde","de","e"]

    image

    示例四 ["abcdef","cdef","ex"]

    image

    示例五 ["abcde","bcdf","cdtks"]

    image

    示例六 ["abc","abcde","abcd","bc","cd"]

    image

    示例七 ["abck","bct","st"]

    image

    fail指针的含义

    假设要以这个字符结尾,哪一个另外的后缀串和其前缀串完全相等

    假设["abcde","bcde","cde","de","e"],所以abcde中e的fail指针指向bcde中的e,因为以abcde中的e的后缀有bcde和候选词bcde的前缀匹配最长。

    匹配规则

    每次来到一个节点,根据fail指针转一圈,如果有描黑的点(结尾点)就收集答案,同时把结尾标志为已处理(防止重复收集),匹配失败的时候,要顺着fail指针蹦到另外一条路径上继续匹配。

    举例

    文章:"abcde"

    候选词:["abc","abcde","abcd","bc","cd"]

    流程:

    第一步,先对候选词建立前缀树并连接好fail指针,建立好以后,如下图

    image

    第二步,文章的逐个位置进行匹配。来到第一个字符a, 前缀树中有走向a字符方向的路。如下图,走到2号点位置:

    image

    然后停在2号点位置,顺着fail指针走一圈,如果有黑色点(结束点)就收集答案。所以,在2号点位置,顺着fail指针走一圈分别要经过2号点,1号点,均不是结尾点,所以没有答案收集。然后再匹配文章的下一个字符b, 前缀树来到如下3号位置节点:

    image

    然后停在3号节点,顺着fail指针走一圈,分别会经历7号节点和1号节点,均不是结尾点,所以未收集到答案。

    继续匹配文章下一个节点c,前缀树来到4号位置:

    image

    然后停在4号位置,顺着fail指针走一圈,分别经历了4号节点,8号节点,9号节点和1号节点,其中4号和8号是结尾点(表示abc的结尾和bc的结尾),所以收集到两个答案abcbc

    继续匹配文章中的d字符,来到5号节点

    image

    然后停在5号节点上,顺着fail指针走一圈,会经历5,10,1号节点,5和10号节点分别是abcdcd的结尾,所以收集到了abcdcd两个答案。

    最后来到文章最后一个节点e,即到6号点位置

    image

    停在6号点位置,顺着fail指针走,经过6号和1号,6号为abcde的结尾,所有收集到了abcde这个答案。

    更多

    算法和数据结构笔记

    参考资料

    程序员代码面试指南(第2版)

    算法和数据结构体系班-左程云

  • 相关阅读:
    十六进制的ASCII码 "u6cf0u56fd" 解码成unicode
    IIS下配置跨域设置Access-Control-Allow-Origin
    IDEAL 中配置Tomcat的内存值
    谷歌浏览器Software Reporter Tool长时间占用CPU解决办法
    关于 java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.String
    通过expdp和impdp将Oracle11g数据导入到oracle10g中
    Oracle数据库执行exp命令--报参数'log' 不允许有多个值
    比较的好与坏
    初版家规
    2016大数据发展七大趋势
  • 原文地址:https://www.cnblogs.com/greyzeng/p/15347534.html
Copyright © 2011-2022 走看看