多正则表达式匹配(Multiple Regular Expression Matching)
目前 febird 中的自动机库已支持正则表达式,并且,支持的是多正则表达式匹配:
这也许是现存的最高效的解决该问题的算法,之前我一直认为该问题很难解决:一个很难的字符串问题,现在,它解决了,世界平静了! 当初我提出该问题的时候,如果我那个时候就开始尝试解决它,也许永远解决不了! 该问题的最终解决,却是源于另外几个问题的解决,当我完美高效地实现DAWG之后,我就在想一个问题:如何实现一个动态的基于 DAWG 的 Map?在自动机的一些算法和应用中,我想象了一个解决方案(类似红黑树索引号),但是后来经过仔细的思考,那个方案根本就行不通! 再后来,我又开始思考短语注音问题,短语注音问题的难点在于短语中的多音字,如果一个短语有多个多音字,这个短语所有可能的注音数量是指数的!如果我们只想从汉字短语得到它的所有可能注音,那这根本就不是问题!短语注音问题是:
这个问题一开始遇到的时候,觉得很困难,也就一直没有太上心,因为这是个Map问题,那个时候在我的大脑中,只有 DAWG 能实现基于 DFA 的 Map,而我知道 DAWG 根本无法解决这种指数问题。 再到后来,偶然一个机会,我也不记得具体的动机是什么,我为 DFA 增加了一个接口:
int match_key(char delim,string text,function<void(int keylen,string value)> on_match); delim 一般是 t ,创建用于该接口的 DFA 时,输入是一行行的 (key,value) 文本: key t value match_key 碰到 t 时,将已匹配的字符串长度作为 keylen , t 后面的部分作为 value,通过 on_match 回调返回给调用方,之所有用回调,是因为在 ADFA 中,同一个 key 对应多个 value 是一种很自然的事情,而这多个 value 可能非常多。总之,从用户来看,这是一个非常简单有效的接口。并且,自动机的创建是一个分离的通用的程序(adfa_build)。这就形成了一个最简单的生态:adfa_build 从文本文件生成 DFA 二进制文件,在线服务器程序加载 DFA 二进制文件并调用 match_key 。 不需要为每一个不同的服务器程序专门写一个 addfa_build ! 然后,我很快就意识到,这可以解决注音问题,关键是生成那个 DFA!最简单的办法是从短语集合生成一个个 (pinyin,汉字) 的 (key,value) pair,这里 key 是拼音,汉字是 value,如果一个短语有多音字,就生成多个 (key,value) pair,先不管对应同一个 value 的 key 数目可能因为多音字从而是指数个。只傻乎乎地将这些 (key,value) pair 输出给 adfa_build 程序,最终肯定能生成那个 DFA,而且是最小化的 DFA,因为该 DFA 创建过程是 Onfly Minimize 的,内存用量不会超爆。但是,但是——内存是不会爆,时间却仍然是指数级的! 这个问题曾经困扰了我很久,那段时间,我日思夜想,就是无法解决指数问题!后来终于有一天,洗澡的时候,我忽然意识到,用 NFA 作为媒介!因为我很早就实现了 Jan Daciuk 的 Onfly ADFA Minimization 算法,在 match_key 给我灵感之后,有一天突发奇想,结合 match_key 的 delim,对 Daciuk 的算法做了一个理论上的泛化: add_adfa_tail,这个 adfa_tail 可以拥有任何复杂的 DAG 结构,如果把那多个可能的注音放到这个 adfa_tail 中,问题就解决了一半,剩下的一半,就是 DFA 的翻转,很简单的事情! ……………… ………… …… 再接下来,灵感继续光临,多正则表达式匹配,只需要在每个正则表达式之后,附加一个 delim+ID,一大半问题就解决了,剩下的一小半,就是纯粹的工程技术问题了 再后来,就是一些优化和泛化问题了,到目前为止,我的 DFA 多正则匹配算法还可以获取一类正则表达式的 submatch……
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ruby-on-rails – 缓存评估导致rails辅助方法的结果
- swift – NSCollectionView dataSource无法正常工作
- XML的标签属性、带参XML
- MongoDB快速入门笔记(八)之MongoDB的java驱动操作代码讲解
- 基于Flash CS5 AS3.0 开发之_TextField中文字体特别注意事项
- c – 无法使用boost :: asio监听UDP端口
- 什么是依赖注入
- ruby-on-rails – 基于数据库的文件系统的Rails实现
- ruby-on-rails – 如何通过Shopify API删除Shopify Webhook
- c# – 如果一次运行一个单元测试则传递正常,如果运行“解决