KMP 算法 非 T[0] = length 型 (一 源文件)

本例中我们使用的是一般的string 而不是T[0] = length

/////////////////////////////////////////////////////////////源文件****************************************************

#include <iostream>
using namespace std;
#define INI_SIZE 100
//=======================
typedef struct
{
 char * base;//the base pointer
    int length;//the string length
}MString;//this string is exist in the heap

int InitString(MString &store,char * input)
{//put the char into the MString;
 store.base = (char *)malloc(INI_SIZE*sizeof(char));
 store.length = 0;
 int i =0;
  int j = 0;
 while(input[i]!=0)
 {
  store.base[j++] = input[i++];
  ++store.length;
 }
 return 0;
}
void show(MString &store)
{
 for(int i =0;i<store.length;++i)
 {
  cout<<store.base[i];
 }
 cout<<endl;
}
int StrCat(MString &str1,MString &str2)//connect the str2 behind the str1
{
 if((str1.length+str2.length)>INI_SIZE)
  str1.base = (char *)realloc(str1.base,(str1.length+str2.length)*sizeof(char));
 int len1 = str1.length;//*/*注意这里的变量 变量是在变化的 不能用变换的东西去干扰const
 for(int k =0;k<str2.length;++k)
 {
  str1.base[len1+k] = str2.base[k];
  str1.length++;
 }
 return 0;
}
int StrCmp(MString &str1,MString &str2)
{//if the str2 is equal to str1 then return 0 else return the str1.length - str2.length
 int i;
 int j;
 i=str1.length;
 j = str2.length;
 while(--i&&--j)
 {
  if(str1.base[i]!=str2.base[j])
   return str1.length - str2.length;
 }
 if(i||j)
  return str1.length - str2.length;
 else
  return 0;
}

int StrSub(MString main,MString &sub,int pos,int length)
{
 //get the substring from the main string from the pos and the length is the sub's
 sub.base = (char *)malloc(INI_SIZE*sizeof(char));
 sub.length = 0;
 for(int i = 0;i<length;++i)//i is just used for count
 {
  sub.base[i]=main.base[pos++];
  ++sub.length;
 }
 return 0;
}
int StrGetLength(MString str)
{
 return str.length;
}

void ClearList(MString &main)
{
 main.length = 0;
 free(main.base);
}
int MoveMatch(MString main_static,MString sub_dynamic)//if return the int it is the first destination index(from 0 to n) of the main string
{
 int i,j;
 i = j = 0;
 while(i<main_static.length && j<sub_dynamic.length)
 {
  if(main_static.base[i] == sub_dynamic.base[j])
  {
   ++i;
   ++j;
  }
  else
  {
   i = i-j+1;
   j = 0;
  }
 }
 if(j == sub_dynamic.length)//in this case the substring is matched
  return (i-sub_dynamic.length);
 else
  return -1;//sub_dynamic can not be matched in the main string k
}

int StrKMPAlog(MString main,MString son)
{
 int i,j,k;
 i=j=0;k = 1;
 while(i<main.length && j<son.length)
 {
  if(main.base[i] == son.base[j])
  {
   i++;
   j++;
   k++;//this parameter is used for accout the number of the equal element
  }
  else
  {
   i=i+k;
   j = 0;
  }
 }
 if(j == son.length)//in this case the substring is matched
  return (i-son.length);
 else
  return -1;//sub_dynamic can not be matched in the main string k
}

int FindNext(MString main,int *next)
{
 int i;//used for go around the next array
 int j;//be the pointer to point to the son String
 //main.base[]
 i = 0;
 j = -1;
 next[0] = -1;
 while(i<main.length)
 {
  if(j == -1||main.base[i] == main.base[j])
  {
   ++i;
   ++j;
   next[i]=j;// when it is equal next[j+1] = k+1;next[j+1] = next[j]+1 as j is added by itself so we can do it like this
  }
  else//reback to the next simililar point and compare
        j=next[j];//change the j by using the next arrary
 }
 return 0;
}
int Kmp(MString main,MString son,int next[])
{
 int mainI =0;
 int sonI = 0;
 while(mainI <main.length && sonI<son.length)
 {
  if(sonI==0||main.base[mainI] == son.base[sonI])
  {
   ++mainI;
   ++sonI;
  }
  else
   sonI = next[sonI];
 }
 if(sonI == son.length)
  return mainI-son.length+1;
 else
  return 0;
}

//*************************************************************************END OF THE SOURCE===============================================

 

 

//====================================================STATR OF THE TEST FUNCTION =======================================

int main()
{
 MString test1,TEST2,test3;
 cout<<"plsez insert some chars"<<endl;
 char*  h1="abababaabaa abaabc bcdcabcd";
 char*  h2="abaabc";
    InitString(test1,h1);
 InitString(TEST2,h2);
 cout<<test1.length<<endl;
 cout<<TEST2.length<<endl;
 cout<<"*-*-*-*-*-**-*-*-*-**---*"<<endl;
  

 //=================strKMP TEST*****************************************************************************************
 //int * next = (int*)malloc(sizeof(int)*TEST2.length);
 int * next = new int[TEST2.length];
    FindNext(TEST2,next);
 for(int i = 0;i<TEST2.length;++i)
  cout<<next[i]<<endl;
 cout<<"KMP"<<
  Kmp(test1,TEST2,next)<<endl;
    system("pause");
 return 0;
}

 

 

kmp 算法的关键是咋next函数的求取 从本质上来说next函数是一个定义域为整数的离散函数
它的目的是求取任意一个字符的回溯位置 next函数有两个重要性质;这两个重要性质是
1、当比较到pj==pi时那么next[j+1] = next[j]+1 就是说next[j+1] = k+1 也就是说在如果两个比

较是相等的话那么后面一个字符的next函数值肯定是前面的加1
2、当比较pj!=pi的时候这个时候 做为模式串就要回溯了,回溯到哪里?回溯到next[j]的位置就是

程序中所写的 j=next[j] j指针的位置发生了变化。

ps:next函数本来就是一种迭代关系的函数 对于这种函数要找到它的规律,从简单的人力劳动中总

结出来一般的原理,当然对于手工的计算也要多做几次,然后让手工的技巧不断模式话,这样的话离

最终写出计算机源代码也不远了、

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值