C++ 为什么KMP中作为后缀计算部分的最长前缀的时间复杂度为O(n),而不是O(n^2)?
我正在浏览KMP的代码,这时我注意到最长的前缀,也是KMP的后缀计算部分。事情是这样的C++ 为什么KMP中作为后缀计算部分的最长前缀的时间复杂度为O(n),而不是O(n^2)?,c++,c++11,C++,C++11,我正在浏览KMP的代码,这时我注意到最长的前缀,也是KMP的后缀计算部分。事情是这样的 void computeLPSArray(char* pat, int M, int* lps) { int len = 0; lps[0] = 0; int i = 1; while (i < M) { if (pat[i] == pat[len]) { len++; lps[i] = len;
void computeLPSArray(char* pat, int M, int* lps)
{
int len = 0;
lps[0] = 0;
int i = 1;
while (i < M) {
if (pat[i] == pat[len]) {
len++;
lps[i] = len;
i++;
}
else
{
if (len != 0) {
len = lps[len - 1]; //<----I am referring to this part
}
else
{
lps[i] = 0;
i++;
}
}
}
}
void计算阵列(字符*pat,整数M,整数*lps)
{
int len=0;
lps[0]=0;
int i=1;
而(i len=lps[len-1];//如果表达式不需要随着len增长而增长的时间
Len是一个整数。读取它需要O(1)个时间
数组索引是O(1)
多次访问某个对象并不意味着您在符号方面更高。只有在某些k的访问计数增长快于kn的情况下。如果仔细分析创建前缀表的算法,您可能会注意到回滚位置的总数最多可能是m
,因此iter总数的上限为平均值是2*m
,它产生O(m)
len
的值随着主迭代器i
的增加而增加,并且每当出现不匹配时,len
会降回零值,但此“下降”不能超过自匹配开始以来主迭代器i
传递的间隔
例如,假设主迭代器i
在位置5开始与len
匹配,在位置20不匹配。
所以
在不匹配的时刻,len
的值为15。因此,它最多可以在15个位置回滚到零,这相当于匹配时通过i
的间隔。换句话说,在每次不匹配时,len
向后移动的距离不超过自匹配开始以来向前移动的i
你想告诉我们什么是“KMP”。@jesper同意,但谷歌KMP算法找到了。字符串搜索。
int a[m];
memset(a, 0, sizeof(a));
for(int i = 0; i<m; i++){
for(int j = i; j>=0; j--){
a[j] = a[j]*2;//This inner loop is causing the same cells in the 1
//dimensional array to be visited more than once.
}
}
while(i<M){
if{....}
else{
if(len != 0){
//doesn't this part cause the code to again go back a few elements
//in the LPS array the same way as the inner loop in my above
//written nested for loop does? Shouldn't that mean the same cell
//in the array is getting visited more than once and hence the
//complexity should increase to O(M^2)?
}
}
}
LPS[5]=1
LPS[6]=2
...
LPS[19]=15