求next数组的两种方法

法一解释:转自http://www.cnblogs.com/yjiyjige/p/3263858.html

     关键运算步骤


 i  0 1 2 3 4 5 6 7 8 9
    A B A C D A B A B C
 a -1 0 0 1 0 0 1 2 3 2
 s[1]!=s[a=0] -> a=next[a=0]=-1 -> next[++1]=++a=0;
 s[2]==s[a=0] -> next[++2]=++a=1;
 s[3]!=s[a=1] -> a=next[a=1]=0 -> s[3]!=s[a=0] -> a=-1 ->s[4]=0;
 s[8]!=s[a=3] -> a=next[a=3]=1 -> s[8]==s[a=1] -> s[++8]=s[9]=++a=2;
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int next1[111111];
char s[]="ABACDABABA";//"ABABCABAA";
void getnext()
{
    int i=0,a=-1;//i代表字符的下标,a代表失配时下一步要移动的位置
    next1[0]=-1;
    while(i<strlen(s))
    {
        if(a==-1||s[i]==s[a])//
            next1[++i]=++a;
        else
            a=next1[a];
    }
    for(int k=0;k<i;k++)
    {
        printf("%d\n",next1[k]);
    }
}
int main()
{
    getnext();
    return 0;
}

法二:运用最大长度表

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
int next[111111];
void next1(char s[],int next[],int n)
{
    next[0]=0;
    int len=0,i=1;//len表示前缀长度
    while(i<n)
    {
        if(s[i]==s[len])//第i个等于第len个
        {
            len++;
            next[i]=len;
            i++;
        }
        else
        {
            if(len>0)
                    len=next[len-1];
            else//也就是len=0的情况
            {
                next[i]=len;//0
                i++;
            }
        }
    }
    for(int i=n;i>0;i--)//值右移一位
        next[i]=next[i-1];
    next[0]=-1;
}
int main()
{
    char s[]="ABABCABAA";
    int p[9];
    next1(s,p,9);
    for(int i=0;i<9;i++)
    {
        printf("%d\n",p[i]);
    }
    return 0;
}

 

posted @ 2018-08-16 21:20  aeipyuan  阅读(2004)  评论(0编辑  收藏  举报