算法设计与分析——Horpool算法(字符串匹配算法)

前言

在一段字符串中,查找另一段字符串是否在此字符串中,如果在,那么其位置是多少?这是一种经典的字符串匹配问题,但是字符串匹配问题其实还有非常多的拓展用法。 从算法的基础出发,应用到实际中,才是这个算法的作用最大体现。例如,搜索引擎中,就有字符串匹配算法的影子,一个好的字符串匹配算法,就能够大大提升一个搜索引擎的搜索速度。

一、算法思想分析

Horspool算法的核心思想是利用预处理的结果来减少字符串的比较过程,这里的预处理是针对需要查找的子字符串(或称作模式串
(以下思想分析篇幅可能有点长,请做好准备,如果不喜欢看大段文字的朋友,也可以先看算法理解再来看分析。)
那么如何对模式串进行预处理?在我们得到模式串时,我们将根据模式串来建立一张移动表,而在模式串和文本(被查找的字符串)比较时,模式串将从左向右移动,每次移动的距离就是由这张移动表决定的。
该移动表对应的是,在本次比较匹配失败后,如果文本中的某个字符与模式串中最后一个字符是比较对象(就是这个两个本次匹配在相互比较),那么模式串需要往右移动的距离。干讲起来有些拗口,举个栗子:在某次匹配时,其匹配结果是失败的,如果这个时候与模式串最后一个字符(具体要看模式串了)对应的字符是w,而在预处理表中,w对应的移动次数是3,那么这个时候模式串就向右移动3个单位(即位置+3),而如果在预处理表中没有w,那么,我们就需要移动模式串的长度个距离。
可是,我们的移动表是怎么得出来的呢?这张移动表的生成正是和它的作用相对应的,为什么我们能够按照如上的方法来使用移动表呢?这就是Horpool算法的精妙之处了。
首先,Horpool算法的字符串比较是从模式串最后一个字符来和文本的对应位置来一个一个比较的。这也就说明了,我们是以模式串的最后一个字符为基准的。想象一下,如果我们有一次匹配失败了,如果在文本中与模式串最后一个对应的字符根本就不在模式串中,我们还有必要一个一个来移动的比较么?是不是可以直接跳过模式串长度个距离来进行下一次匹配?而相对应的,如果这个对应的字符在模式串中,那么我们是不是只要移动模式串中这个字符距模式串最后一个字符的最近距离?注意一下,这里必须是最近距离!
所以,我们的移动表生成方法出来了。对模式串进行处理,将模式串中有的字符与这个字符距最后一个字符串的距离做对应,就生成了移动表了,而不再模式串的,一概对应的都是模式串的长度。但是,这个地方我们需要注意的是,这个距离最小是1,不存在0。
光说的话可能有点稀里糊涂,下图举个栗子来说:
匹配串示例
上图不仅将移动表附上,比较过程同样附上,可以看出,第五次比较已经匹配成功,大家可以参考一下。下面再附上《算法设计与分析基础》中的示例来帮助大家更好的理解。
字符串匹配示例
所以,算法思想总结为:
算法思想总结

二、算法效率分析

假设模式串的长度为m,文本长度为n。那么在最差的情况下,算法效率是 O(n*m) ,看起来似乎是和蛮力法(一个一个的去比较。。。)差不多的。但是对于随机文本来说,Horpool算法的效率是处于 O(n) 的,只有在极端情况(也就是最坏情况)下才会出现 O(n*m) 的情况。平均来说,Horpool算法显然是比蛮力法快得多的。

三、算法代码

C语言代码</

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值