From:http://www.yuanma.org/data/2008/0806/article_3128.htm
摘要:随着互联网的日渐庞大,信息也是越来越多,如何在海量的信息中快速查找自己所要的信息是网络搜索研究的热点所在,在这其中,字符串匹配算法起着非常 重要的作用,一个高效的字符串匹配算法,可以极大的提高搜索的效率和质量,本文力图阐明字符串匹配算法的发展过程,并介绍了各个算法的特点,并给予了适当 的比较和分析。
关键字:字符串匹配 前缀 后缀 kmp算法 后缀树
Abstract: with internet booming, the amount of information gets more and more. How to find the target information in such tramendous data is the key in web searching develepment. In this end the string matching algorithm takes the key role. An efficient string matching algorithm can improve web searching service greatly. The author try to introduce the developing of the string matching algorithm and emphasis on kmp and suffix tree algorithm.
Keywords: string matching suffix prefix KMP suffix tree
1.引言
查找模式字符串在文本中的所有出现是文本编辑软件经常要面对的一个问题。一般而言文本就是要编辑的文档,而模式字符串往往由用户来指定,高效的字符串匹配 算法可以提高程序的响应性能,当然字符串匹配算法的应用远远不止于此,例如在生物计算科学中查找特定的DNA序列,也是字符串匹配算法的一个重要应用。
我们可以如下定义字符串匹配问题,我们假定文本是一个长度为n的字符数组T[1..n],而模式字符串也是一个字符数组P[1..m],并且m <= n。进一步的,我们假定T所包含的所有字符构成一个有限的字符表E,|E|表示字符表所包含的自负的个数。
本文所提及的字符串匹配算法除了朴素字符串匹配算法以外都需要一定的预处理时间,此预处理时间根据算法的不同也不尽相同,图1展示了本文将要提到的各个算 法所需要的预处理时间以及匹配的时间,可以大致看出字符串匹配算法的演变过程,而且会发现后缀树算法与其他算法有很大的不同,而正是由于这一点使得后缀树 的应用更加贴近于今天互联网的大环境。
2.朴素字符串匹配算法
朴素字符串匹配算法的思想非常直白,既然是查找模式字符串在文本字符串中的出现,那么我么就从文本字符串的每一位开始一次判断是否与模式字符串相同,如果 相同那么就找到了模式字符串的一次出现,可以看出此算法的时间复杂度为O(mn),m,n分别为文本字符串与模式字符串的长度,但是通过更加深入的分析可 以得出此算法的平均时间复杂度为O(n+m),所以此算法在模式字符串与文本字符串都是随即选择的情况下工作地是相当的不错,还有就是此算法并没有其他算 法所必须的预处理时间。
3.Rabin-Karp算法
Rabin-Karp算法是由Rabin和Karp[1]提出的一个在实际中有比较好应用的字符串匹配算法,此算法的预处理时间为O(m),但它的在最坏 情况下的时间复杂度为O((2n-m+1)m),而平均复杂度接近O(m+n),此算法的主要思想就是通过对字符串进行哈稀运算,使得算法可以容易的派出 大量的不相同的字符串,假设模式字符串的长度为m,利用
Horner法则p = p[m] + 10(p[m -1] + 10(p[m-2]+...+10(p[2]+10p[1])...)),求出模式字符串的哈稀值p,而对于文本字符串来说,对应于每个长度为m的子串的 哈稀值为t(s+1)=10(t(s)-10^(m-1)T[s+1])+T[s+m+1],然后比较此哈稀值与模式字符串的哈稀值是否相等,若不相同, 则字符串一定不同,若相同,则需要进一步的按位比较,所以它的最坏情况下的时间复杂度为O(mn)。
4.字符串匹配自动机
与字符串相关的自动机[2]是一个五元组(Q,q,A,E,%)其中Q是状态的有限集合,q<Q是开始状态,A<+Q是接受状态的集合,E是 输入字符集合,%是一个QXE->Q的映射,称为转移函数。通过模式字符串,我们可以构造出识别此字符串的自动机,此自动机对应于字符表中的任何一 个输入在某个状态下都有一个转移到另一个状态(包括它自身),当进行到接受状态时就找到了模式字符串在目标字符串中的一次出现,由于自动机需要对于任何一 个字符集中出现的字符都给出相应的转移,也就意味着构造自动机的时间复杂度与|E|有关,而事实上,构造自动机的时间复杂度为O(m^3|E|),但当此 自动机构造完成后,搜索目标字符串的时间为O(n)。
5.KMP算法
现在要提到一个伟大的算法,它的出现归功于Knuth,Morris和Pratt的伟大工作[3],此算法采用类似上面所提到的字符串自动机的原理,但完 全避免了计算转移函数,它仅仅用了一个只需要O(m)就能计算出来的辅助函数pai[1..m]就达到了搜索时间复杂度为O(n).
函数pai称为前缀函数,是根据模式字符串构造的,对于一个给定的模式字符串p[1..m],它的前缀函数定义如下:pai[q] = max{k:k<q and p(k) > p(q)}即:pai[q]是p的最长的与后缀p(q)相同的前缀。
通过均摊分析可以证明计算前缀函数的时间复杂度为O(m),而同样把此方法用于分析KMP算法的时间复杂度分析,我们可以得出KMP匹配算法的时间复杂度为O(m+n)。
6.后缀树算法
6-1后缀字典树算法
对于目标字符串的所有后缀,可以把他们构造成字典树,此字典树的每一个节点(除叶子节点外),都可能有|E|个分支,这样在目标字符串中搜索模式字符串的 出现变得非常的简单,只需要从字典树的跟节点出发,按照对应的分支向下查找,最多比较m次,就可以确定此模式字符串是否在目标字符串钟出现。所以查找字符 串的时间复杂度为O(m)与目标字符串n无关,这种好处是非常明现的,它意味着对于一个目标字符串一旦建立它的后缀字典树后,以后在此目标字符串查找任意 字符串都只需要O(m)的比较,但是构造后缀字典树无疑是很花费时间与空间的,通过分析可以知道,构造此字典树的时空花费为O(n^2),对于很大的目标 字符串来说,这是无法忍受的。
6-2非在线后缀树算法
为了减少构造后缀字典树所花费的时间与空间,Edward McGreight[4] 1976年发表了后缀树的论文,此后缀树与后缀字典树在代表的含义上完全相同,但由于它采用了路径压缩的方法,即每条边不只代表一个字符,有可能是一个字 符串,大大节省了构造此后缀树所花的时间与空间,可以证明此后缀树最多有2n个节点,构造的时间为O(n),但是此算法有个非常明显的缺点,就是它的倒序 处理字符串的,也就是它是非在线的。
6-3在线后缀树算法
1995年Ukkonen[5]提出了在线的后缀树算法,支持从左到右的输入字符串,并在输入的同时构造出后缀树,至此给后缀树画上了完美的句号,通过分析可以知道基于后缀树的字符串匹配算法的时间复杂度为O(m+n)。
7.总结
通过上面的阐述,我们可以清出的看出一个问题的提出经常半随着一个新算法的出现,而一个新算法的出现又会带来一些新的问题。前面所述的这些算法虽然从理论 上来说一个比一个高效,但是在实际应用中,每个算法都有自己独特的价值,即便是最原始的朴素字符串匹配算法也仍然有较好的应用,因为它的平均性能很好,而 且不需要预处理时间。而Rabin-Karp算法则往往用于单个模式字符串在多个目标字符串中的同时查找,以及模糊匹配。KMP无疑是应用最广的而且它的 实现也很简单,几乎无所不在。后缀树算法对于在同一个目标文本中查找多个模式字符串则非常的适合,尤其对于很大的目标文本,工作地非常好,所以在网络搜索 中成为了主流算法。目前后缀树的研究已经比较成熟,主要在进行后缀数组的研究,后缀数组与后缀树的想法相同,但是在实现上更加高效,不过它并不是O(n) 的算法,但是由于其简单的结构,高效的实现使得它的应用非常的诱人。字符串匹配算法还有很多,这里只是提到一些比较经典的算法,不过沿着字符串匹配算法的 轨迹,我们可以清楚的看到它的迷人之处。
Reference
[1]Richard M.Karp and Michael O.Rabin. Efficient randomized pattern-matching algorithms. Technical Report Tr-31-81,aiken Computation Laboratory.Harward University,1981.
[2]Alfred V.Aho,John E.Hopcroft,and Jeffrey D.Ullman. The Design and Analysis of Computer Algorithms.Addison-Wesley,1974.
[3]Donarld E.Knuth. Big omnicron and big omega and big theta.ACM SIGACT News, 8(2). 18-23,1976.
[4]E.M.Mclreight. A Space-Economical Suffix Tree Construction Algorithm. Jrul of Algorithms,23(2) pp262-272,1976.
[5]E.Ukkonen. On-line Construction of Suffix Trees. Algorithmica,14(3)pp249-260,1995.
[6]Mark Nelson.Fast String Searching with Suffix Trees.Dr. Dobb's Journal August,1996.
[7]P.Weiner. Linear Pattern Matching Algorithms.Proc.14th IEEE Annual Symp on Switching and Automata Theory,pp1-11,1973.
[8]D.E.Knuth,J.H.Morris and V.R.Pratt. Fast Pattern Matching in Strings. SIAM Jrul Comput,6(2) p323-350 Jun,1997.
[9]G.de V.Smit. A comparision of Three String Matching Algorithms.Software Practice and Experience 12 p57-66 Jan, 1982.
[10]T.H.Cormen,C.E.Leiserson,R.L.Rivest and C.Stein. Introduction to Algorithms(2nd edition). The MIT Press.
[11]http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/Suffix
[12]http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Strings
[13]http://www.cise.ufl.edu/~sahni/dsaaj/enrich/c16/suffix.htm
分享到:
相关推荐
研究结果显示,在高速网络环境中,高效的字符串匹配算法对于提高系统的性能至关重要。 #### 六、未来发展方向 针对未来的研究方向,本文提出以下几点建议: - **算法优化**: 继续优化现有算法,特别是在处理大...
13. **Z-Algorithm**:线性时间复杂度的字符串匹配算法,可以找出字符串的所有子串位置。 14. **Trie数据结构**:又称字典树,用于高效存储和检索前缀匹配的字符串。 15. **Suffix Array** 和 **Longest Common ...
4. **生物信息学**:在基因组学研究中,字符串查找被用于比对DNA序列,寻找相似的基因片段。 ### 字符串查找算法 常见的字符串查找算法有: - **KMP算法**:Knuth-Morris-Pratt算法,通过预处理模式串的next数组...
Z算法是一种线性时间复杂度的字符串匹配算法,由日本科学家Mori和Ogura提出。它能在O(n)的时间内计算出一个字符串的所有子串的最长前缀与后缀的最大长度,从而快速进行模式匹配。Z算法的基本思想是动态构建一个Z...
- **应用实例**:例如,`[a-zA-Z]+` 可以用来匹配所有由字母组成的连续字符串。 - **优化策略**:考虑到正则表达式的计算成本较高,在实际应用中需要根据具体的性能需求进行权衡。 ### 基于分词器的字符串分割 ...
字符串匹配算法的任务是在文本T中找出模式P的所有出现位置。该问题有几个常用的表示符号,包括n和m分别表示模式P和文本T的长度,Σ表示字符集,Pi表示P中的第i个字符,而x,y,z表示字符串。举一个简单的例子:如果T=...
可以考虑使用KMP、Boyer-Moore或其他高效的字符串匹配算法来提高效率。 通过学习这个压缩包中的源码,你可以深入了解易语言的字符串处理能力,并掌握文本替换的核心技巧。同时,这也是一次实践和提高易语言编程技能...
通过研究这个源码,你可以深入理解正则表达式匹配的实现细节,学习如何在易语言环境下编写高效的字符串处理程序。同时,这也是一次将理论知识转化为实际代码的实践机会,有助于提升编程和问题解决能力。 在分析源码...
此外,还有字符串匹配算法(如KMP,Boyer-Moore),回溯法,分支限界法等。这个Java算法大全涵盖了这些基础和进阶的算法,对提升编程能力和解决问题的能力有着显著帮助。通过深入研究这些源代码,不仅可以理解算法的...
6. **字符串处理**:如KMP算法、Boyer-Moore算法等,用于高效的文本匹配;还有动态规划解决的最长公共子序列问题,在生物信息学等领域中有重要应用。 7. **递归与回溯**:递归是解决复杂问题的有效工具,但需注意...
2. **字符串处理**:掌握在易语言中如何处理和操作字符串,如分割、比较、查找等。 3. **拼音库**:学习如何使用或编写拼音库,将汉字转换为拼音,这是进行首拼和双拼匹配的基础。 4. **模糊匹配算法**:深入研究...
动态模拟演示2.7z可能会包含排序(如冒泡排序、选择排序、插入排序、快速排序、归并排序等)、搜索(如线性搜索、二分搜索)、图算法(如深度优先搜索DFS、广度优先搜索BFS、Dijkstra最短路径算法、Floyd-Warshall...
8. **字符串处理**:如KMP匹配算法、Rabin-Karp字符串搜索算法等,用于处理字符串的比较和查找。 9. **数值计算与近似算法**:如牛顿迭代法、二分法等,这些方法常用于求解数学问题。 10. **位运算**:C语言中的位...
9. **字符串处理**:KMP算法、Rabin-Karp算法等用于字符串匹配,Z-Algorithm、Manacher's Algorithm用于处理字符串的重复问题。 10. **数学算法**:如大整数运算、矩阵乘法、素数检测等,常用于密码学和计算几何等...
8. **字符串处理**:KMP算法、Boyer-Moore算法等字符串匹配算法,以及Z算法、Manacher's算法等用于解决字符串处理问题。 9. **递归与分治**:如快速幂运算、归并排序、分治求解斐波那契数列等,这些都是复杂问题...
6. **字符串处理**:KMP算法用于模式匹配,Rabin-Karp算法用于字符串搜索,Z函数和Manacher's算法用于找到字符串中的最长回文子串。 7. **数据结构**:链表、栈、队列、树(如二叉搜索树、平衡树AVL和红黑树)、...
字典编码是通过存储前缀字符串来减少重复数据,而匹配查找则是寻找最长的重复前缀,以此提高压缩效率。在源代码中,这些算法的实现涉及了高级的数据结构和算法设计,如动态哈希表和滑动窗口。 其次,文件格式解析器...
LZMA算法通过查找重复的字符串并用更短的代码来表示它们,从而实现数据压缩。同时,它还引入了熵编码,如Huffman编码或Range编码,进一步优化压缩效果。 7Z的源码包含了整个7-Zip软件的实现,包括文件管理、压缩...
7. **字符串处理**:JavaScript在处理字符串时有许多内置函数,但自定义算法可以提供更高效的方法,比如KMP算法、Z-Algorithm等用于字符串匹配,Manacher's Algorithm用于找出字符串中最长的回文子串。 8. **性能...
8. **字符串处理**:KMP、Rabin-Karp和Boyer-Moore等字符串匹配算法在处理文本问题时非常重要。Z-Algorithm和Manacher's Algorithm则用于找出字符串中的最长回文子串。 9. **位运算**:C++的位运算对于优化代码和...