C++ 为什么KMP中作为后缀计算部分的最长前缀的时间复杂度为O(n),而不是O(n^2)?

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;

我正在浏览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; 
          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;
而(ilen=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