NO.1 BF(Brute Froce),MP

本文详细介绍了BF(暴力匹配)算法和MP(Morris-Pratt)算法的基本原理及应用。通过实例说明了两种算法的具体操作流程,并重点阐述了MP算法如何通过失效函数避免不必要的回溯,提高匹配效率。
         ***BF(Brute Froce)***

看着是不是有点蒙,不知道这是啥?!
简单一点吧,我都不知道,原来这也是个算法……


   挨个字符比较。
   就是我们没学算法前,都会用的一种,只是名字比较高端了而已。
   
        A:121232
        B:232
    从A的第一个字符与B的字符进行比较,1—2不符合,然后A的第二个字符与B的字符比较(从B的第一个字符开始),2—-2,1—–3,不符合,然后A的第三个字符B的字符比较(从B的第一个字符开始),1—2,不符合,然后A的第四个字符B的字符比较(从B的第一个字符开始),2–2, 3—3, 2—-2,比较成功,完成!

               ***MP***

     我知道,看到了MP,大家以为我打错了,不是KMP吗?
     其实,MP也是一种算法,而且,正如大家所想象的一样,它与KMP算法有着密切的联系。

   MP算法避免了BF中频繁的回溯,又称为不回溯的字符串搜索算法。算法复杂度O(M+N)。
   MP中,遇到了不匹配的字符,指针不必回溯,而是利用已得到的部分匹配结果,将模式向右滑动若干后,继续比较。//现在不理解不要紧,继续看下面,会理解的。
   
   T(目标串):ctcaatcacaatcat
    P(模式串):caatcat

    从T的第一个字符与P的字符进行比较,c——c, t—–a,不符合,然后,字符串P向后移动一位; 然后,t—c,不符合;再向后移动一位……
    细心的同学可能会发现,当进行第二轮以后的匹配时,可以先进行P串自身的匹配。
    所以,这就用到了失效函数,下面举个例子,怎样获取实现函数: 
   
    P的失效函数
定义域:0~Len(P)-1(//Len(P)字符串的长度);
值域:k 属于{x|0<=x小于j }
若k不存在,失效函数的取值为-1.
当j=0, k可能的取值不存在,f(0) = -1;
当j=1, k可能的取值0,p0!=p1, f(1) = -1;
当j=2, k可能的取值0, 1,p0!=p2, p0p1!=p1p2,f(2) = -1;
……
失效函数示例:
- j 0, 1 , 2 , 3, 4, 5, 6
- P(j) c, a , a, t, c, a, t
- f(j) -1, -1, -1, -1, 0, 1, -1

得到失效函数之后,就可以运用MP算法进行匹配。
1. c—-c, t—–a,不符合,目标指针不回溯,失配发生在第二个位置,所以,j=1,模式P在下一轮的起始地址是Pf(j-1)+1,即P0。
2. t—-c,不符合,j=0, 目标指针前进一位。
3. c—–c, a—–a, a—-a, t—-t, c——c, a——a, c——t, 不符合,j=6, Pf(6-1)+1, 即P2。
4. ……

一直到匹配成功。
MP算法的时间复杂度为O(n+m).

#include <iostream>
using namespace std;
void preMp(const char *x, int m, int mpNext[])
{
  int i, j;
  i = 0;
  j = mpNext[0] = -1;
  while(i<m)
  {
     while(j>-1&&x[i]!=x[j])
     j = mpNext[j];
     mpNext[++i] = ++j;
  }
}
void MP(string p, string t)
{
    int m = p.length();
    int n = p.length();
    if(m>n)
    {
      cerr<<"Unsuccessful match!"<<endl;
      return ;
    }
    const char * x = p.c_str();
    const char * y = t.c_str();
    int i = 0, j = 0, mpNext[m+1];
    preMp(x, m, mpNext);
    while(j<n)
    {
      while(i>-1 && x[i] != y[j])
      {
        i = mpNext[i];
        i++;
        j++;
        if(i>=m)
        {
          cout<<"Matching index found at: "<<j-1<<endl;
          i = mpNext[i];
        }
      }
    }
}

推荐一篇写的十分的好的博客

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值