next数组完美诠释

来源:互联网 发布:数控车床编程100例 编辑:程序博客网 时间:2024/06/05 01:52

例子:
原串:ABCDABCDABDE
子串:ABCDABD

a,b,c,a,b,d,a,b,c, a, b, c 字母
0,0,0,1,2,0,1,2,3, 4, 5, 3 next[]

//这个串的起始位置为1

0 X X X X X X X X
    i
next[i]表示到i当前位置,前缀==后缀的数目
如果j=next[i-1],且s[i]==s[j+1]
那么,next[i]=j+1;

否则的话
j=next[j];//不用直接跳到第一个去匹配
再判断是否相等,直到j=0
while(j>0 && s[i]!=s[j+1]) j=next[j];

如果不满足要求跳出while,判断是s[i]==s[j+1]呢,还是j==0呢?
如果s[i]==s[j+1],则next[i]=j+1;
如果j==0,则next[i]=0; //模拟一下,j=0,j+1=1,s[j]!=s[i],则next[i]=0;

写成完整的程序就是:
next[1]=0;//第一个字母是没有前缀后缀的
for(int i=2;i<=strlen(s+1);i++)
{
j=next[i-1];//前一个i的next
while(j>0 && s[i]!=s[j+1]) j=next[j];
if(s[i]==s[j+1]) next[i]=j+1;
else next[i]=0;
}

完整版:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int next[10000];char sa[10000],sb[1000];int main(){    cin>>sa+1;    cin>>sb+1;    int lena=strlen(sa+1);    int lenb=strlen(sb+1);    int st=0,ed=0,j=0;    for(int i=1;i<=lena;i++)    {        while(j>0 && sa[i]!=sb[j+1]) j=next[j];//为什么要比较s[i]和s[j+1],而不是s[i]和s[j]?        //因为不同要往回翻,翻到相同之处,比较下一位是否相同,这样写比较方便         if(sa[i]==sb[j+1]) j++;        if(j==lenb) {st=i-lenb+1,ed=i;break;}    }       if(j==lenb) cout<<st<<" "<<ed<<endl;    else cout<<"No"<<endl;    return 0;}
原创粉丝点击