常见算法及问题场景——字符串匹配

思路

字符串匹配的思路大致分几种:

1、暴力匹配。

2、基于暴力匹配进行优化。
进行预计算,一旦发现失败匹配之后,可以跳过更多的位置,减少无谓的浪费。
这篇文档提到了许多按这个思路实现的算法各具特点
http://blog.csdn.net/airfer/article/details/8951802/
但最具代表性的算法还是KMP,这篇文档讲的非常详细:
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

3、AC自动机。
根据原始字符串,及模式字符串,初始化DFA,计算出转移矩阵。接下来检验原始字符串是否可以被DFA所接受即可。
转移矩阵在这种情况下为稀疏矩阵,为了压缩空间,通常使用trie(字典树)来实现。字典树中的边表示匹配路径上的字符,节点存储当前索引,next指针数组,fail指针。
fail指针的指向,跟KMP算法有共性,在匹配失败时可以跳过无效的匹配。
关于AC自动机,可以参考这里:
http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html
关于DFA的原理,可以参考这里:
http://metc.gdut.edu.cn/compile/cmpl3/3-3.htm

字典树的应用:
在搜索引擎的分词操作中,使用的词库中的词条数目往往几十万以上,为了保证切分速度,一个好的词库查找方法很重要。一个比较经典的方法就是使用Trie树结构来组织词条,使用树节点存储词条中的字符,使用hash来寻找字符在Trie树中的位置,使用最大长度查找方法来匹配词条。

特殊字符串模式识别
有些字符串的模式有自己的内在规则,像电话(86-13088438874)、地址(北京市朝阳区大望路)、组织机构(阿里巴巴集团有限公司)等。
要识别这类字符串,可以构造出不同规则的状态机,进行规则的判断和状态跳转。

4、hash值匹配。实现非常简单的Rabin-Karp算法。预计算出模式字符串的hash code,然后依次从原始字符串中取出模式字符串等长的部分,计算其hash code,看两个值是否相等。匹配失败则后移一位,继续匹配。
思路比较新颖,效率波动比较大。
可参考这篇文档:
http://blog.csdn.net/lalor/article/details/7318401

效率对比

DFA与KMP最优。

具体可参考这里:
http://www.cnblogs.com/feature/articles/1813967.html

你可能感兴趣的:(数学之美)