Prefix Function Algorithm
The Prefix Function Algorithm is an efficient string matching algorithm that is mainly used to find all occurrences of a pattern within a given text or to determine the longest proper prefix that is also a suffix for a given string. It is commonly used in various applications, such as text search, data compression, and computational biology. The algorithm computes an auxiliary array, usually called the prefix function or the longest proper prefix-suffix array, which stores the length of the longest proper prefix that is also a suffix for each position in the input string. The prefix function algorithm is based on the observation that once a match of a given pattern is found within the text, the algorithm can reuse the previously computed prefix function values to avoid unnecessary comparisons and speed up the search process.
The algorithm starts by initializing an array of zeros, where the size of the array is equal to the length of the input string. It then iterates through the string from left to right, maintaining a counter variable to keep track of the length of the current longest proper prefix that is also a suffix. At each step, the algorithm compares the characters at the current position and the position indicated by the counter variable. If they match, the counter is incremented, and the value is stored in the prefix function array. If they do not match, the algorithm checks if the counter has a non-zero value and updates the counter with the prefix function value at the previous position. If the counter is zero, the algorithm moves on to the next position in the input string. Once the array is fully computed, the algorithm can use it to efficiently find all occurrences of a pattern within the given text or to determine the longest proper prefix that is also a suffix for any given substring.
/*************************************************************************************
Prefix function. O(N)
About it: http://e-maxx.ru/algo/prefix_function
Based on problem 1323 from informatics.mccme.ru:
http://informatics.mccme.ru/mod/statements/view3.php?id=241&chapterid=1323
*************************************************************************************/
#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cassert>
#include <utility>
#include <iomanip>
using namespace std;
const int MAXN = 1000100;
int n;
string s;
int p[MAXN];
int main() {
//assert(freopen("input.txt","r",stdin));
//assert(freopen("output.txt","w",stdout));
getline(cin, s);
n = (int) s.length();
for (int i = 2; i <= n; i++) {
int prev = p[i - 1];
while (prev > 0 && s[prev] != s[i - 1])
prev = p[prev];
if (s[prev] == s[i - 1])
prev++;
p[i] = prev;
}
for (int i = 1; i <= n; i++)
printf("%d ", p[i]);
return 0;
}