KMP

#include <iostream>
using namespace std;
// 已知nextval向量的情况下,如何进行模式匹配
int GetIndex(const char *src, const char *pattern, int nextval[])
{
  // 若匹配成功,返回匹配起点下标,否则返回-1
	int i = 0; //主串的下标
	int j = 0; //模式串下标
	while(src[i] != '\0' && pattern[j] != '\0')
	{
	   if(src[i]==pattern[j])
	   {
	     i++;
	     j++;
	   }
	   else
	   {
	      if(nextval[j] == -1) //模式串已没有可以匹配的位置了
		  {
		     i++;
		     j=0; //从头开始匹配
		  }
		  else
		  {
		     j = nextval[j] ; 
		  
		  }
	   
	   }
	
	}

	return pattern[j]=='\0' ? i-j : -1 ;  
   
}

int getnextval(const char *pattern, int nextval[])
{
   int k = -1 ; //最大相同 首真子串和尾真子串,
   // 为了让k1 = 0;则让k0 = -1,k1=0表示模式串第1个字符不匹配时,从第0个字符开始

   nextval[0]  = -1 ;// 第0个实符匹配失败,表示模式串根本没有可能匹配的位置了
   for(int i=1 ; pattern[i] != '\0' ; i++)
   {
	 //要是pattern[i] != pattern[k]时,则又是一个模式匹配问题,则 k = nextval[k],直到匹配,或者根本没有可能匹配,k=-1表示根本没有可能匹配
     
	   while(k != -1 && pattern[i-1] != pattern[k] ) k = nextval[k] ;
       k++ ; //要是已经匹配了,则k++,  要是根本没有可能匹配 了,k++刚好k=0 表示从第 0 个字符开始
    
	   
	   // 校正得到nextval[i]
	   if( pattern[i]== pattern[k])
		   nextval[i] = nextval[k] ; 
	   else
         nextval[i] = k; 
   }
   return 1;
}


int main()
{
  char src[100] ="abaabaaaaab";
  char pattern[20] = "aaaab" ;
  int nextval[100] ;
  getnextval(pattern, nextval);
 int pos = GetIndex(src,pattern,nextval);
 cout<<"源串为"<<src<<endl;
 cout<<"模式串为"<<pattern<<endl;
 cout<<"匹配的开始位置是:"<<pos<<endl;
 system("pause");
 return 0;
}

你可能感兴趣的:(KMP)