KMP算法(《算法导论》)

本文介绍了KMP算法,一种用于字符串匹配的高效算法。通过计算模式的前缀函数,KMP可以在源字符串中查找模式的出现位置。文章提供了C++实现,并详细解释了算法的每个步骤。
摘要由CSDN通过智能技术生成

#include 
< iostream >
#include 
< string >
#include 
< assert.h >
using  std:: string ;
using  std::cout;
using  std::endl;
class  KMP
{
 
public:
    KMP(
char* source, char*Pattern):source(source),Pattern(Pattern){V = NULL;}
    KMP(
const KMP& rh)
    
{
        assert(
&rh != this);
        source  
=  rh.source;
        Pattern 
= rh.Pattern;
        V 
= rh.V;
    }

    KMP
& operator=(KMP& rh)
    
{  
        assert(
&rh != this);
        source  
=  rh.source;
        Pattern 
= rh.Pattern;
        V 
= rh.V;
        
return rh;
    }

    
int* Compute_Prefix_Function(char* Pattern)
    
{
      
int m = strlen(Pattern);
      V 
= new int[m];
      memset(V, 
0, m * sizeof(int));
      V[
0= 0;
      
int k =0 ;
      
for(int q = 2; q < m; q++)
      
{   
        
while((k > 0&& (Pattern[k+1!= Pattern[q]))
            k 
= V[k];
        
if(V[k] == Pattern[q-1])
            k 
= k + 1;
        V[q
-1= k;
      }

      
return V;
    }

   
void    KMP_Matcher()
    
{
      
int n = strlen(source);
      
int m = strlen(Pattern);
      
int* V = Compute_Prefix_Function(Pattern);
      
int q = 0;
      
for(int i = 1; i <=n; i++)
       
{
         
while(q > 0 && Pattern[q] != source[i-1])
            q 
= V[q-1];
          
if(Pattern[q] == source[i-1])
            q 
= q + 1;
          
if(q == m)
          
{
           cout
<<" Pattern occurs with shift  " <<i-m<<endl;
           q 
= V[q-1];
           }

        }

        
    }

~KMP(){ delete []V; }
 
private:
    
char* source;
    
char* Pattern;
    
int* V;
}
;


int  main( int  argc,  char *  argv[])
{   
    
char m[] = "l111111112klajia211bcabd112";
    
char n[] = "112";
    KMP par(m, n);
    KMP pa 
= par;
    pa.KMP_Matcher();
    
return 0;
}

//  KMP.cpp : Defines the entry point for the console application.
//
// 《算法导论》569页。模式匹配在于计算前缀与后缀的匹配,只有这样,才能把
// 前缀移位到当初匹配的后缀。因为是在前缀和后缀匹配的情况下。
#include  " stdafx.h "
#include 
< iostream >
#include 
< string >
using  std:: string ;
using  std::cout;
using  std::endl;

int *  Compute_Prefix_Function( char *  P)
{
    
int m = strlen(P);//计算模式的长度
    int *= new int[m];//申请空间
    memset(V, 0, m*sizeof(int));//初始化为0
    V[0= 0;
    
int k =0 ;
    
for(int q = 2; q < m; q++)
    
{   //V[k]实际上是指第k个字符的最长前缀和后缀相等.《算法导论》(图32—10 |图32-11)有详细说明.
        while((k > 0&& (P[k+1!= P[q]))//当第k+1个字符和第q个字符不相等,本质就是V[k+1]不存在前缀和后缀相等
            k = V[k];//循环搜索所有的V[k]值,直到找到一个P[k+1] ==P[q]的值为止。还存在k=0和p[0] ==p[q-1]的情况
        if(V[k] == P[q-1])
            k 
= k + 1;
        V[q
-1= k;
    }

    
return V;
}

void  KMP_Matcher( char *  T,  char *  P)
{
    
int n = strlen(T);
    
int m = strlen(P);
    
int* V = Compute_Prefix_Function(P);
    
int q = 0;
    
for(int i = 1; i <=n; i++)
    
{
        
while(q > 0 && P[q] != T[i-1])
            q 
= V[q-1];
        
if(P[q] == T[i-1])
            q 
= q + 1;
        
if(q == m)
        
{
        
          cout
<<" Pattern occurs with shift  " <<i-m<<endl;
          q 
= V[q-1];
        }

        
    }

    
   delete []V;
}



int  main( int  argc,  char *  argv[])
{   
    
char m[] = "l111111112klajia211bcabd112";
    
char n[] = "112";
    KMP_Matcher(m, n);
    
return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yshuise

权术横行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值