数据结构–KMP算法进一步优化(nextval)
在KMP算法中,nextval
数组是对应于next
数组的一个优化。nextval
数组的作用是在匹配失败时,可以跳过一些不必要的字符比较,从而提高匹配的效率。
nextval
数组的计算方式和next
数组类似,但是在计算过程中引入了一个新的指针k
。k
指向的是当前位置的前缀的末尾位置,即pattern[k]
是当前位置的前缀的最后一个字符。k
的初始值为0。
与next
数组不同的是,在计算nextval[i]
时,如果pattern[i]
与pattern[j]
不相等,则需要根据next[j]
的值来更新j
和k
的值。具体的更新规则如下:
- 如果
next[j]
为0,则将j
和k
都加1。 - 如果
next[j]
不为0,则将j
更新为next[j]
,而k
保持不变。
然后,将j
的值赋给nextval[i]
。这样,nextval
数组就得到了更新。
在匹配过程中,如果在位置i
和j
处的字符不匹配,那么根据nextval[j]
的值,可以直接将j
更新为nextval[j]
,而无需再次比较pattern[i]
和pattern[j]
。这样可以跳过一些不必要的字符比较,提高匹配的效率。
代码一:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void getNextvalArray(const char* pattern, int* nextval) {
int n = strlen(pattern);
int j = 0;
int k = -1;
nextval[0] = -1;
while (j < n - 1) {
if (k == -1 || pattern[j] == pattern[k]) {
j++;
k++;
if (pattern[j] != pattern[k]) {
nextval[j] = k;
} else {
nextval[j] = nextval[k];
}
} else {
k = nextval[k];
}
}
}
int main() {
const char* pattern = "ababaca";
int n = strlen(pattern);
int* nextval = (int*)malloc(n * sizeof(int));
getNextvalArray(pattern, nextval);
printf("Nextval Array: ");
for (int i = 0; i < n; i++) {
printf("%d ", nextval[i]);
}
printf("\n");
free(nextval);
return 0;
}
代码二:
typedef struct
{
char ch[15];
int length;
}SString;
int next[15], nextval[15];
void Get_Nextval(SString T)
{
nextval[1] = 0;
int i = 1, j = 0;
while (i <= T.length)
{
if (j == 0 || T.ch[i] == T.ch[j])
{
i++;
j++;
if (T.ch[i] != T.ch[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
}
else
j = nextval[j];
}
}
已知next数组求nextval数组
void Get_Nextval(SString T)
{
nextval[1] = 0;
for (int i = 2; i <= T.length; i++)
{
if (T.ch[i] == T.ch[next[i]])
nextval[i] = nextval[next[i]];
else
nextval[i] = next[i];
}
}