KMP匹配算法

KMP匹配算法是当模式串在字符串发生匹配时,而不用在字符串回溯一种模式匹配查询方法。
假设pat=’a b c a b c a c a b’,如果有si=a且si+1!=b,那么进行si+1与a的比较,如果sisi+1=ab且si+2!=c,则出现如下情况:
s=’a b ? ? ?…..?’,符号”?”表示不知道s中此处字符是什么,在s中第一个”?”代表si+2且Si+2!=c, 因此,索搜的下一步应该是对pat的首字符和si+2比较,而无须比较pat的首字符和si+1,因为已经知道si+1与pat的第二个字符相同为b,即si+1!=a,依次类推,假设出现了pat前四个字母的匹配,然后失配,即si+4!=b,则出现一下情况:
s=’a b c a ? ? …..?’
pat=’a b c a a b……b’
因此有以下结果:
定义:令p=p0p1……pn-1是一个模式,则其失配函数f定义为:
KMP
例如,对于模式pat=abcabcacab,有:
j: 0 1 2 3 4 5 6 7 8 9
pat: a b c a b c a c a b
f: -1 -1 -1 0 1 2 3 -1 0 1
匹配规则:如果出现了形如si-j….. si-1= p0p1….pj-1且si=pi的部分匹配,那么,若j!=0,则下一趟模式匹配时,从失配字符si和模式串字符pf(j-i)+1处重新开始比较,而若j=0时,则继续比较si+1和p0.注意:f1(j)=f(j),fm(j)=f(fm-1(j)).
KMP算法的关键就是要计算出模式串的失配时其位置可以对应模式串重新匹配的位置,其表达式为:
KMP
核心代码:

#include <iostream>
#include<stdio.h>
#include<string.h>
//字符串和模式串的最大长度
#define max_string_size 100
#define max_pattern_size 100
//计算模式串的匹配位置
void fail();
//保存模式串对应位置的匹配信息
int failure[max_pattern_size];
char string[max_string_size];
char pat[max_pattern_size];
using namespace std;
//模式匹配函数
int pmatch();
void fail(char *pat)
{
   int n=strlen(pat);
   failure[0]=-1;
   for(int j=1;j<n;j++)
   {
      int i=failure[j-1];
      //查找j位置字母前一个匹配位置
      while((pat[j]!=pat[i+1])&&i>=0)
         i=failure[i];
      //若当前位置等于查找的位置后一个字母
      //则当前配置匹配为i+1,否则就没有匹配的位置
      if(pat[j]==pat[i+1])
      {
         failure[j]=i+1;
      }
      else
         failure[j]=-1;
   }
}
int pmatch(char *string, char *pat)
{
   int i=0,j=0;
   int lens=strlen(string);
   int lenp=strlen(pat);
   while(i<lens&&j<lenp)
   {
      //若匹配则匹配下一个
      if(string[i]==pat[j])
      {
         i++;
         j++;
      }
      //没有模式匹配时,则匹配字符串下一个
      else if(j==0)
      {
         i++;
      }
      //查找模式对应位置的匹配位置
      else
      {
         j=failure[j-1]+1;
      }
   }
}

经过分析可知道该KMP算法在处理模式匹配的算法时间复杂度是O(strlen(string)+strlen(pat)),而常规的匹配时间复杂度是O(strlen(string)*strlen(pat)).

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值