zoukankan      html  css  js  c++  java
  • 正则转nfa:bug出现。

    本人写的一个正则到nfa的bug

    刚写完前面的那篇,自己用脑子过了一下,发现了一个bug。具体情况如下。

    这个bug的产生条件是多次调用假名的时候,每次调用都会修改假名的nfa图。直接这么说不好理解,我就拿例子来讲吧。假设我们已经定义了一个假名num,而现在我们有一个正则表达式调用了两次这个假名,nums:[num][num],根据前面那篇文章里面所谈到的方法,会生成如下所示的nfa。这里假设num的开始节点为1,结束节点为2。

                           

    但是由于两个节点1和两个节点2引用的是相同的位置,所以上面的图等价于下面的图。

     

    可以明显的看出这个并不是我们所需要的规则,图中所表示的是[num]+。之所以出现这种错误,是因为每次引用这个假名的时候,都会修改里面的内部节点。为了改掉这个bug,则必须在每次引用一个假名的时候,都生成两个新的节点,作为假名的头节点和尾节点。这个头节点与子节点的头节点有空转换边,同时子节点的尾节点到尾节点也有空转换边。这样就可以保证不会出现修改内部节点的情况了。修改后的nfa如图所示。

     

    这个图可以简化为以下的图

     

    可以看出,这个仍然不是我们所需要的规则,前面的那些设想都是错误的。

    没办法,只有一个方法可以彻底解决这个假名问题,就是每次引用一个假名时,都生成一个这个假名的nfa的副本,并重命名节点的标号。在前面的代码中,我们构建了可以使用的信息。因为在生成假名的nfa之后,我们保留了他的开始节点和结束节点。从他的开始节点开始,遍历他的邻接表,每次碰到一个节点的时候,生成一个新的节点来替代原来的节点,并拷贝她的邻接表,并修改邻接表,使他指向一个新的等价的标号。由此我们就生成了一个等价的nfa图。每一个原来的nfa图的节点都有且只有一个处于新的nfa图的节点与之相配对。

    具体代码将在下一篇中实现。

  • 相关阅读:
    【BZOJ3998】弦论(后缀自动机)
    【BZOJ4566】找相同字符(后缀自动机)
    AtomicInteger在实际项目中的应用
    ElasticSearchserver操作命令
    照猫画虎学gnuplot之折线图
    HDU 5667 :Sequence
    mycat 连续分片 -> 按日期(天)分片
    DM8168 unrecoverable error: OMX_ErrorBadParameter (0x80001005) [resolved]
    多线程(一):初识多线程
    Vb.net/VB 声明API函数实现父窗口功能
  • 原文地址:https://www.cnblogs.com/huangfeidian/p/3152705.html
Copyright © 2011-2022 走看看