算法设计:精确字符串匹配

首先来学学精确字符串匹配:

那我们要怎么找呢?:

 

好麻烦,有没有别的?:

指纹就是一个标识符,但这个标识符怎么找呢?

就是把每个字母当成一位十进制数的数字,我开头记录下目标的字符串是什么数字,然后再一个一个向前比较,数字相同就找到了。这和上面的暴力搜索一样也是一个一个向前找,但这个在比较m个字符串的时候复杂度大大降低了,总是只要改变2位,m再大也不怕。

但这个方法显然存在缺点。我要把一个字符串变成一个数,假如这个字符串很大,那这个数字就要大的受不了。我们来学习新的方法:

同一个数mod 了右mod,结果是一样的,所以这个公式是正确的。

 

现在介绍的方法都有一个问题,那就是每次比较都没有使用之前的知识,每次都重新比较。我想让每个字符都只匹配一次:

简单来讲,PI[q]的计算方法就是:计算我们要找的字符串P中前q个字符中,前缀等于后缀的最大部分。例如:

这样,我们在实际寻找这个字符串的时候,假如遇到了“有一部分相等”的情况,我们可以根据之前相等的部分直接跳过中间部分,利用了之前的记忆。

 

 

 

就比如开头的那一步,我发现头5个相等,第6个不等,我看一看我的PI[]数组,发现PI[5]=3,也就是说头三个和后三个是一样的,所以我们直接跳到后三个,这样就可以快很多了。

 

现在我们来看看逆方法:

 

就是反过来的暴力算法。

 

 

简单来说就是:我比较了一下P和我们目前搜索的部分,发现不一样,那我就看一下我搜索的部分的最后那个字符,看一下:我的P要往前走几位才能遇到和这一位相等的?移动的位数就是shift[字符]的大小。例如我发现最后一个字符是e,那我要往前走4位才能遇到下一个e,所以shift[e]=4.假如最后哪一位压根就不在P里,那当然就直接是移动m位欲避之而不及。

 

 

 

最后这两种方法都运用了“记忆”。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值