关于字符串算法的总结

原创 2013年12月04日 22:25:35

趁着做presentation的时候,顺便把自己最近学习的几种常用字符匹配算法藤上博客和大家分享下。。有什么不懂的地方,可以指出相互交流

  首先是KMP算法。

这个算法实在是太有名了,大学上的算法课程除了最笨的Brute Force 算法,然后就介绍了KMP 算法。也难怪,呵呵。谁让Knuth D.E. 这么world famous 呢,不仅拿了图灵奖,而且还写出了计算机界的Bible <The Art of Computer Programming>这个算法是算法书上一般都有的。在此也就不赘述了。

  当然,有市场就有竞争,字符串匹配这么大一个市场,不可能让BF 和KMP 全部占了,于是又出现了几个强劲的对手。

Horspool算法
Boyer-Moore算法 
Sunday算法
RK算法
下面简要介绍下这几个主要算法的思想:

Horspool 算法的思想很简单的。不过有个创新之处就是模式串是从右向左进行比较的。很好很强大,为后来的算法影响很大。
匹配串:abcbc sdccdab

模式串:cbcac
这个时候我们从右向左进行对暗号,c-c ,恩对上了,第二个b-a ,不对啊,我们应该怎么办?难道就这么放弃么。于是,模式串从不匹配的那个字符开始从右向左寻找匹配串中不匹配的字符b 的位置

匹配串:abcbcsdccdab
模式串: cbcac
这个算法的效率还比较高,不过最坏情况下不如kmp的

第二个上来的是Boyer-Moore 算法。
是一个很复杂的算法,当然,虽然理论上时间复杂度和KMP 差不多,但是实际上却比KMP 快数倍,可见实践是检验真理的唯一标准。

分为两步预处理,第一个是bad-character heuristics ,也就是当出现错误匹配的时候,移位,基本上就是做的Horspool 那几个操作
第二个就是good-suffix heuristics ,当出现错误匹配的时候,我还要从不匹配点向左看啊,以前匹配的那段子字符串是不是在模式串本身中还有重复的啊,有重复的话,那么我就直接把重复的那段和匹配串中已经匹配的那一段对齐

其实第二条规则和kmp有点相似,都做了子字符串的预处理,要用数组保存。
演示
匹配串:abaccba bbazz
模式串:cbadcba

匹配串:abaccbabbaz z
模式串:    cbadcba
然后有时候我们会发现:
匹配串:abacccb bbazz
模式串:cbadccb
这种情况是只有部分匹配的,所以

匹配串:abacccbbbazz
模式串:         cbadccb

最后一个是Sunday 算法,实际上比Boyer-Moore 还快,呵呵。长江后浪推前浪。
思想也更简单。
Sunday 的算法思想和Horspool 有些相似,但是。当出现不匹配的时候,却不是去找匹配串中不匹配的字符在模式串的位置,而是直接找最右边对齐的右一位的那个字符在模式串的位置。

比如:
匹配串:abcbc zdxzc
模式串:zbcac

这里我们看到b-a 没有对上,我们就看匹配串中的z 在模式串的位置,然后,嘿嘿。
匹配串:abcbczdxzc
模式串:          zbcac
如果模式串中的没有那个字符怎么办呢?很简单,跳过去呗

在串匹配的简单算法中,把文本每m个字符构成的字符段作为一个字段,和模式进行匹配检查。如果能对一个长度为m的字符
串赋以一个Hash函数。那么显然只有那些与模式具有相同hash函数值的文本中的字符串才有可能与模式匹配,这是必要条件
   用这个思想就是我们的RK算法了。我挺喜欢的。

事实上,之前的串匹配方法,是将模式串的一个一个字符作为小的特征去分别进行匹配,而RK算法则是将串整体作为一个
特征!难就难在单个字符的特征很容易想得到,整体作为一个特征就没那么容易想得到了。。。貌似和我们之前学的聚类分析有点异曲同工之妙。

用这个思想可以设计有针对性的匹配代码。
我举个简单的例子、
把字符串看做一个26进制数
然后由于可能模式串太长,不能用一个数表示,我们就会想到用hash,用一个大质数取模,只有匹配串中取模后的值和模式串一样才进行比较。。

所以匹配串需要进行一次预处理,进行取模运算,保存在一个新的数组。预处理的具体实现的方法有点巧妙的,用到一点数论的知识。有兴趣的可以去研究下。

ps,需要说明的是strstr是c语言提供的字符串匹配函数,而他使用Brute Force实现的,此处看出有时候暴力法并不一定就那么差,并且简单易懂。

上面的都是些思想,至于算法实现还是要有一些trick的,大家可以自己Google

相关文章推荐

字符串匹配算法总结

  • 2012年08月21日 12:42
  • 111KB
  • 下载

数据结构与算法分析笔记与总结(java实现)--字符串5:词语变形练习题

数据结构与算法分析笔记与总结(java实现)--字符串5:词语变形练习题

数据结构与算法分析笔记与总结(java实现)--字符串面试指南

数据结构与算法分析笔记与总结(java实现)--字符串面试指南

字符串匹配相关算法总结

字符串匹配定义:文本是一个长度为n的数组T[1…n], 模式是以个长度m P和T的元素都是有限字母表∑中的字符 ‍ 1.字符串朴素匹配 也就是蛮力匹配,每次移动一个步长,然后匹配,时间复杂度...

数据结构与算法分析笔记与总结(java实现)--字符串6:两串旋转练习题(*)

数据结构与算法分析笔记与总结(java实现)--字符串6:两串旋转练习题(*)

(笔试前准备)字符串匹配算法总结

我想说一句“我日,我讨厌KMP!”。 KMP虽然经典,但是理解起来极其复杂,好不容易理解好了,便起码来巨麻烦! 老子就是今天图书馆在写了几个小时才勉强写了一个有bug的、效率不高的KMP,特别是计...

字符串全排列算法学习总结

刷题遇到了这个全排列的算法题目,头好疼,整理下各种算法。 学习了这个博主的文章,感谢感谢http://www.cnblogs.com/cxjchen/p/3932949.html...

字符串匹配算法总结 (分析及Java实现)

字符串模式匹配算法(string searching/matching algorithms) 顾名思义,就是在一个文本或者较长的一段字符串中,找出一个或多个指定字符串(Pattern),并返回其...
  • chndata
  • chndata
  • 2015年02月13日 10:58
  • 11639

数组循环移位算法(左旋字符串)【总结】

问题:定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。要求时间对长度为n的字符串操作的复杂度为O(...

字符串算法(KMP+MANACHER+EX_KMP)总结

字符串算法: 1、 KMP算法 2、 MANACHER算法 3、 EX_KMP算法
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于字符串算法的总结
举报原因:
原因补充:

(最多只允许输入30个字)