#include"wz.h"
void getnext1( const char *T, int next[])
{  // 求模式串T的next函数值并存入数组 next。
       int j = 0, k = -1;
       next[0] = -1;
       while ( T[j/*+1*/] != '\0' )
       {
              if (k == -1 || T[j] == T[k])
              {
                     ++j; ++k;
                     if (T[j]!=T[k])
                            next[j] = k;
                     else
                            next[j] = next[k];
              } 
              else
                     k = next[k];
       } 
        for(i=0;i<j;i++) cout<<next[i];
        cout<<endl;
   }
 
void getnext2(  const char* pattern,int next[])
{
       next[0]=  -1;
       k=-1,j=0;
       while(pattern[j] != '\0')
       {
              if(k!= -1 && pattern[k]!= pattern[j] )
                     k=next[k];
              ++j;++k;
              if(pattern[k]== pattern[j])
                     next[j]=next[k];
              else
                     next[j]=k;
       }
   
    for(i=0;i<j;i++) cout<<next[i];
        cout<<endl;
}
int test1()
{
char s[]="aaaab";
int next[10]={0};
getnext1(s,next);
//getnext2(s,next);
return 0;
}
int KMP(const char *Text,const char* Pattern) //const 表示函数内部不会改变这个参数的值。
{
       if( !Text||!Pattern|| Pattern[0]=='\0' || Text[0]=='\0' )//
              return -1;//空指针或空串,返回-1。
       int len=0;
       const char * c=Pattern;
       while(*c++!='\0')//移动指针比移动下标快。
       {    
              ++len;//字符串长度。
       }
       int *next=new int[len+1];
       int index=0,i=0,j=0;
       while(Text[i]!='\0' && Pattern[j]!='\0' )
       {
              if(Text[i]== Pattern[j])
              {
                     ++i;// 继续比较后继字符
                     ++j;
              }
              else
              {
                     index += j-next[j];
                     if(next[j]!=-1)
                            j=next[j];// 模式串向右移动
                     else
                     {
                            j=0;
                            ++i;
                     }
              }
       } 
       delete []next;
       if(Pattern[j]=='\0')
              return index;// 匹配成功
       else
              return -1;      
}
void test2() 
{
       //char text[]="aaab";
       //char pattern[]="ab";
char text[]="abaabcac";
char pattern[]="a";
      cout<<KMP(text,pattern)<<endl;
}


int next[100];  
void getnext(char *b)  
{  
    int i = 1, j = 0;  
    next[1] = 0;  
    while(i <= strlen(b))  
    {  
        if(j == 0 || b[i - 1] == b[j - 1])  
        {  
            i++;  
            j++;  
            next[i] = j;  
        }  
        else  
        {     
            j = next[j];  
        }  
    }  
} 
int kmp(char *a,char *b)  
{  
    int i = 1, j = 1; //i是主串中的位子 ,j匹配串的位子  
    while(i <= strlen(a) && j <= strlen(b))  
    {  
        if(j == 0 || a[i - 1] == b[j - 1])  
        {  
            i++;  
            j++;  
        }  
        else   
            j = next[j];  
    }  
    if(j > strlen(b))  
        return i - strlen(b);  
    else  
        return 0;  
} 
//匹配算法:主串s,模式t  
int index(char *s, char *t)  
{  
    // int i = 0, j = 0;  
    while(i < strlen(s) && j < strlen(t))  
    {  
        if(s[i] == t[j])   
        {  
            i++; j++;  
        }  
        else //每一趟匹配失败时重新计算主串s和模式串t的索引  
        {  
            i = i - j + 1;  
            j = 0;  
        }  
    }  
  
    if(j >= strlen(t)) //匹配成功  
        return i - j + 1;  
    else               //匹配失败  
        return -1;  
}  
char *mystrstr(char*s1,char*s2)
{
    if(*s1==0)
    {
        if(*s2) return (char*)NULL;
        return (char*)s1;
    }
    while(*s1)
    {
        int i=0;
        while(1)
        {
            if(s2[i]==0)
                return s1;
            if(s2[i]!=s1[i])
                break;
            i++;
        }
        s1++;
    }
    return (char*)NULL;
}
char *gcc480_strstr(const char*s1,const char*s2)
{
    const char*p=s1;
    const size_t len=strlen(s2);
    for(;(p=strchr(p,*s2))!=0;p++)
    {
        if(strncmp(p,s2,len)==0)
            return (char*)p;
    }
    return 0;
}
char *old_strstr(const char*s1,const char*s2)
{
    int n=0;
    if(*s2)
    {
        while(*s1)
        {
            for(n=0;*(s1+n)==*(s2+n);n++)
            {
                if(!*(s2+n+1))
                    return(char*)s1;
            }
            s1++;
        }
        return NULL;
    }
    else
        return (char*)s1;
}
int main()
{
char text[]="cccabaabcac";
char pattern[]="abc";
 	   cout<<"kmp:"<<kmp(text,pattern)<<endl;
       cout<<"index:"<<index(text,pattern)<<endl;
       cout<<"mystrstr:"<<mystrstr(text,pattern)<<endl;
       cout<<"gcc:"<<gcc480_strstr(text,pattern)<<endl;
 	   cout<<"old_strstr:"<<old_strstr(text,pattern)<<endl;
       return 0;
}