KMP 算法

KMP算法核心

    next函数:

1.定义:

    next[k] =

 1)  k = 1时,next[k] = 0;

 2)  = max( k | { 1 < k < j ) { p[1...k-1] = p[j-k+1...j-1] }

 3)  其他情况 next[k] = 1

 

2.递推求解

1) 定义,next[1] = 0, 假设next[j] = k, p[1..k-1] = p[j-k+1..j-1]

2)  若p[j] = p[k], p[1..k] = p[j-k+1..j], next[j+1] = next[j] + 1 = k + 1;

3) 若p[j] != p[k],匹配失败时 k = next[j];

View Code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int next[10000];
int nextval[10000];

//求next函数 
/*
1.next[1] = 0;
2.'p1..pk-1' = 'pj-k+1..pj-1'
3.pj = pk
  next[j+1] = next[j] + 1;
  pj != pk
  此时把求next函数看作一个模式匹配问题,整个模式串既是主串
  又是模式串。
*/

 
void get_next(char *st)
{
   next[1] = 0;
   int i = 1, j = 0;
   int len = strlen(st + 1);
   while( i <= len )
   {
      if( st[i] == st[j] || j == 0 )
      {
          i++, j++;  
          next[i] = j;  
          
      }
      else
         j = next[j];
          
   }
     
}
/*

next函数优化版

* /
void get_nextval(char *st )
{
   int i = 1, j = 0;
   nextval[1] = 0;
   int len = strlen( st + 1);
   while( i <= len )
   {
      if( j == 0 || st[i] == st[j] )
      {
         i++, j++;
         if( st[i] != st[j] )  nextval[i] = j;
         else nextval[i] = nextval[j];    
      }       
      else
      j = nextval[j];    
   }      
     
}

/*
在匹配过程中产生失配:
1. 指针i不变,指针j退回到next[j]所指示的位置上进行比较。
2. 当指针j退至0时, 指针i, 指针j都需要同时加1
*/
 
int Index_KMP(char *str, char *st, int pos )
{
    
    int i = pos, j = 1;
    int len1 = strlen(str+1);
    int len2 = strlen(st+1);
    while( i <= len1 && j <= len2 )
    {
       if( str[i] == st[j] || j == 0 )
       {
          ++i, ++j;               
       } 
       else
       j = next[j];      
           
    }   
    if( j > len2 )
    {
       return i - len2;    
    }
    else
    return 0;
} 

int main( )
{
  
  char str[10000];
  char st[100];
  while( scanf("%s%s", str + 1,st + 1) != EOF )
  {
         
    memset(next, 0, sizeof(next));
    printf("%s\n%s\n",str+1, st+1);
    get_next( st  );
    printf("%d\n", Index_KMP(str, st, 1));
       
         
  }
  return 0;  
}

转载于:https://www.cnblogs.com/tangcong/archive/2012/07/20/2601194.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值