定义


前缀函数

前缀函数(π数组),也叫即最长真前缀真后缀(lps数组,Longest prefix which is also suffix)。

过程


定义i, j两个指针,i用于匹配后缀,j用于匹配前缀,初始时i = 1, j = 0

pattern[i] == pattern[j]时,匹配成功,j++lps[i] = j

pattern[i] != pattern[j]时,匹配失败,若j != 0(即存在已经匹配的前缀pattern[0...j - 1]),此时有pattern[0...j - 1] == pattern[i - j...i - 1]
此时pattern[i - j...i - 1](也就是pattern[0...j - 1])无法作为pattern[i]pattern[j]的共同前缀,因此需要在pattern[0...j - 1]中找到一个最长真前缀(这个前缀同时也是pattern[i - j...i - 1](也就是pattern[0...j - 1])的最长真后缀)使得pattern[i] == pattern[j],即需要找到pattern[0...j - 1]的最长真前缀真后缀,所以令j = lsp[j - 1],若依然pattern[i] != pattern[j],重复上述操作,直至匹配成功(j++lps[i] = j)或j == 0lsp[i] = 0)。

模版


int N, lps[N]; \\ lps[i]默认为0
void LPS(string pattern)  
{  
    for (int i = 1, j = 0; i < pattern.size(); i++)  
    {  
       while (j > 0 && pattern[i] != pattern[j]) \\ 匹配失败
          j = lps[j - 1];  \\ 从最长真前缀真后缀开始寻找下一个可能的前缀
       if (pattern[i] == pattern[j]) \\ 匹配成功
          lps[i] = ++j;
    }  
}

示例


对于字符串str = ababac

istr[0…i]lps[i](π[i])
0a0规定lsp[0] = 0
1ab0没有相等的真前缀和真后缀
2aba1最长真前缀真后缀为a
3abab2最长真前缀真后缀为ab
4ababa3最长真前缀真后缀为aba
5ababac0没有相等的真前缀和真后缀