‘壹’ kmp算法中的next到底是什么意思啊
先看看next数据值的求解方法
位序 1 2 3 4 5 6 7 8
模式串 a b a a b c a c
next值 0 1 1 2 2 3 1 2
next数组的求解方法是:
1.第一位的next值为0
2.第二位的next值为1
后面求解每一位的next值时,根据前一位进行比较
3.第三位的next值:第二位的模式串为b ,对应的next值为1;将第二位的模式串b与第一位的模式串a进行比较,不相等;则第三位的next值为1
4.第四位的next值:第三位的模式串为a ,对应的next值为1;将第三位的模式串a与第一位的模式串a进行比较,相同,则第四位的next值得为2
5.第五位的next值:第四位的模式串为a,对应的next值为2;将第四位的模式串a与第二位的模式串b进行比较,不相等;第二位的b对应的next值为1,则将第四位的模式串a与第一位的模式串a进行比较,相同,则第五位的next的值为2
6.第六位的next值:第五位的模式串为b,对应的next值为2;将第五位的模式串b与第二位的模式中b进行比较,相同,则第六位的next值为3
7.第七位的next值:第六位的模式串为c,对应的next值为3;将第六位的模式串c与第三位的模式串a进行比较,不相等;第三位的a对应的next值为1,则将第六位的模式串c与第一位的模式串a进行比较,不相同,则第七位的next值为1
8.第八位的next值:第七位的模式串为a,对应的next值为1;将第七位的模式串a与第一位的模式串a进行比较,相同,则第八位的next值为2
以上这种分析方法,位序是从1开始的,如果位序从0开始,刚第一位的next值为-1,后面的方法则相同
‘贰’ 谁能解释数据结构中KMP算法的next函数
假如str的前j个字符是前i个字符的后缀(j<i),那么next[i]就是所有这样的j的最大值
形象地说,就是假如第i+1个字符匹配失败之后,下一个可能匹配位置至少应该往后挪动多少
就"abaabc"而言
next[1]=0
next[2]=0
next[3]=1
next[4]=1
next[5]=2
next[6]=0
计算过程基本上抄自算法导论,假设str长度为n
k=0;//k表示当前匹配了多少位
next[1]=0;
for (i=1;i<n;i++)
{
while (k && str[i]!=str[k]) k=next[k];
if (str[i]==str[k]) k++;
next[i+1]=k;
}
之后计算str和某个长度为m的字符串text匹配的过程基本上是一样的
k=0;//用于记录str最长能够有前k位是text的前i+1个字符的后缀
for (i=0;i<m;i++)
{
while (k && text[i]!=str[k]) k=next[k];//发现不能匹配的时候就把str往后挪
if (text[i]==str[k]) k++;
if (k==n) printf("在位置%d处找到一个匹配\n",i+1-n);
}
对照着后面这一段很容易理解第一段
‘叁’ 给出字符串在KMP算法中的Next数组
逐个查找对称串。
只要循环遍历这个子串,分别看前1个字符,前2个字符,3个... i个 最后到15个。
第1个a无对称,所以对称程度0
前两个ag无对称,所以也是0
依次类推前面0-4都一样是0
最后一个是0~3都一样是0
前缀next数组的求解算法:
void SetPrefix(const char *Pattern, int prefix[])
{
int len=CharLen(Pattern);//模式字符串长度。
prefix[0]=0;
for(int i=1; i<len; i++)
{
int k=prefix[i-1];
//不断递归判断是否存在子对称,k=0说明不再有子对称,Pattern[i] != Pattern[k]说明虽然对称,但是对称后面的值和当前的字符值不相等,所以继续递推
while( Pattern[i] != Pattern[k] && k!=0 )
k=prefix[k-1]; //继续递归
if( Pattern[i] == Pattern[k])//找到了这个子对称,或者是直接继承了前面的对称性,这两种都在前面的基础上++
prefix[i]=k+1;
else
prefix[i]=0; //如果遍历了所有子对称都无效,说明这个新字符不具有对称性,清0
}
}
(3)kmp算法next计算扩展阅读:
设主串(下文中我们称作T)为:a b a c a a b a c a b a c a b a a b b
模式串(下文中我们称作W)为:a b a c a b
用暴力算法匹配字符串过程中,我们会把T[0] 跟 W[0] 匹配,如果相同则匹配下一个字符,直到出现不相同的情况,此时会丢弃前面的匹配信息,然后把T[1] 跟 W[0]匹配,循环进行,直到主串结束,或者出现匹配成功的情况。这种丢弃前面的匹配信息的方法,极大地降低了匹配效率。
而在KMP算法中,对于每一个模式串我们会事先计算出模式串的内部匹配信息,在匹配失败时最大的移动模式串,以减少匹配次数。
‘肆’ 数据结构 KMP算法 求next值
暂时只帮你改正了编译错误:
#include<iostream>
using namespace std;
#include<string.h>
typedef struct
{
char data[20];
int length;
}sqstring;
void getnext(sqstring* t,int next[])
{
int j,k;
j=0;
k=-1;
next[0]=-1;
while(j<t->length-1)
{
if(k==-1||(t->data[j]=t->data[k]))
{ j++; k++;
next[j]=k;
}
else k=next[k];
}
}
main()
{
int i,JG[20];
sqstring* t;
t=(sqstring *)malloc(sizeof(sqstring));
char h[20];
gets(h);
for(i=0;h[i]!='\0';i++)
t->data[i]=h[i];
t->length=i;
getnext( t, JG);
for(i=0;i<=20;i++)
cout<<JG[i]<<endl;
}
‘伍’ kmp算法next(j)怎么算出来的
int first=-1,last=0;
len=strlen(ch);
while(last<len){
if(ch[first]==ch[last] || first==-1){
first++;last++;
next[last]=first;
}
else
first=next[first];
}
用自己和自己KMP然后得出next[]
最后的出来的就是next[]了,当然我这个next[]是初值为-1的,你书上写的应该是最大匹配值,就是将我的全部左移一位的结果
‘陆’ KMP算法中next的求解方法
求法(s为字符串)
next[1]=0;
next[2]=1;
next[i]=max{k|(k<i)且(s[1]...s[k-1]=s[i-k+1]...s[i-1])}
P.S:问错分类了?
‘柒’ KMP算法求next数组的问题
字符串如果是以0为下标的话next[7]是0,只有最后一位与第一位相等。
在第i个字符前面的i-1个字符里面,
从开头开始的1个字符与最后1个字符是否相等,若不是,则next[i]=0;
从开头开始的2个字符与最后2个字符是否相等,若不是,则next[i]=1;
从开头开始的3个字符与最后3个字符是否相等,若不是,则next[i]=2;
前缀next数组的求解算法:
void SetPrefix(const char *Pattern, int prefix[])
{
int len=CharLen(Pattern);//模式字符串长度。
prefix[0]=0;
for(int i=1; i<len; i++)
{
int k=prefix[i-1];
//不断递归判断是否存在子对称,k=0说明不再有子对称,Pattern[i] != Pattern[k]说明虽然对称,但是对称后面的值和当前的字符值不相等,所以继续递推。
(7)kmp算法next计算扩展阅读:
kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和m,判断f是否在O中出现,如果出现则返回出现的位置。常规方法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的复杂度是O(nm)。kmp算法通过一个O(m)的预处理,使匹配的复杂度降为O(n+m)。
‘捌’ KMP算法next数组的计算
字符串如果是以0为下标的话next[7]是0,只有最后一位与第一位相等
‘玖’ KMP算法中的next数组如何计算
next[i]表示的是:
在第i个字符前面的i-1个字符里面,
从开头开始的1个字符与最后1个字符是否相等,若不是,则next[i]=0,否则继续看下面;
从开头开始的2个字符与最后2个字符是否相等,若不是,则next[i]=1,否则继续看下面;
从开头开始的3个字符与最后3个字符是否相等,若不是,则next[i]=2,否则继续看下面;
……
就是这样的判断取值。
它的意思就是如果到了某个字符不匹配的情况时候,你就可以直接把模式串拖到从开头开始的那next[i]个字符等于当前字符的前next[i]个字符的地方,这样就少了很多重复的无效的比较和移动。
‘拾’ KMP算法next函数
设主串为S = "s1s2 ... sn",模式为T = "t1t2 ... tm"
当“失配”(si <> tj)时,模式串T “向右滑动” 的可行距离有多远? 或者说,下一步si 应该与模式串中的哪个字符比较,这完全取决于模式串,与主串无关
因此,可以预先为模式串设定一个数组next[j],当“失配” (si <> tj)时,i 不变,j 改为next[j]
0 当j = 1时,不比较
next[j] = max{k, 1 <= k < j 且"t1 … tk-1" = "tj-(k-1) … tj-1"}
1 其他情况
next[j] 函数表征着模式T 中最大相同首子串和尾子串(真子串)的长度
相似部分越多,则next[j] 函数越大
既表示模式T 字符间的相关度越高,也表示j 位置以前与主串部分匹配的字符数越多
next[j] 越大,模式串向右滑动得越远