kmp

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;

char boss[200],pattern[200];

//next表明的是字符串覆盖自己的性质也就是k值(也就是说next[j]=k)(j跟我写的文章中不太一样啊。)
//我们要算next[6]的值,有关的为P本身前6个字符010010 。(这个就是例子)
//此字符串中010 = 010左右相同的最大字符串为010,个数为3。所以next[i]=3;
int next[200];

int max(int a,int b)
{
    if(a>b) return a;
    return b;
}

void getnext(char pattern[])
{
 //初始化为0
    memset(next,0,sizeof(next));


    int i=-1,j=0;//i=-1的时候是为了下面的i++


    next[0]=-1;//第一个肯定是-1


    while(j<strlen(pattern))
    {
           if(i==-1||pattern[i]==pattern[j])
     {
               i++;  j++;  
               next[j]=i;
           }
           else i=next[i];
    }
}

 


//获取的是开始匹配的位置

//其实文章中跟论文中有一点出入
//因为annb和anna比较的时候,后来移动的时候j=3,也就是从不匹配的那一位算的。
int KMP(char boss[],char pattern[])
{
    int i=0,j=0,len1=strlen(boss),len2=strlen(pattern);

 //文章中所说的跳过,是没有比较的操作
    while((i<len1)&&(j<len2))
    {
  //j==-1表示没有一个相同的。i表示匹配到的字符串(母串),j表示的是开始比较是否匹配的字符串(模式串)
        //当j==-1的时候需要i++,j++(),因为这个表示从第0个元素开始重新匹配。+1以后的值为0,才开始判断。

  //如果相同的话,也就是继续匹配下一个
  if(j==-1||boss[i]==pattern[j]) 
  {
   j++;i++;
  }

  //如果不相同的话,移动。
        else 
   j=next[j];//取出next[j]
    }

 //len2是模式串的长度,j是模式串的指针,也就是说如果说完全匹配,返回的是开始的位置
    if(j==len2) 
  return i-len2;

 //如果不匹配,返回-1
    else 
  return -1;
}

//获取的是匹配的长度
int index_KMP(char boss[],char pattern[])
{
    int i=0,j=0,len1=strlen(boss),len2=strlen(pattern),re=0;
    while(i<len1&&j<len2)
    {
  if(j==-1||boss[i]==pattern[j]) {i++;j++;}
        else j=next[j];
        re=max(re,j);
    }
    return re;
}

int main()
{
 freopen("in3.txt","r",stdin);
 while(scanf("%s",boss)!=EOF)
 {
  scanf("%s",pattern);
  getnext(pattern);
  printf("%d %d\n",KMP(boss,pattern),index_KMP(boss,pattern));
 }
 
    return 0;
}

//在那个表格当中i相当于最上面的一行。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值