Определение
Дана строка длины , префикс-функция в позиции — это длина наибольшего собственного префикса подстроки
Дана строка длины , префикс-функция в позиции — это длина наибольшего собственного префикса подстроки
Решите эти внешние задачи (например, из Codeforces) чтобы закрепить материал урока:
который также является суффиксом этой подстроки.
Здесь собственный префикс означает префикс, который не равен всей строке целиком.
Поэтому всегда имеем:
и для :
Например, для строки
префикс-функция равна
Чтобы эффективно вычислить префикс-функцию, мы используем несколько важных наблюдений.
Для каждого имеем:
Это означает, что значение префикса может увеличиться не более чем на единицу при переходе к следующей позиции.
Предположим, мы уже знаем .
Пусть
Тогда мы пытаемся продлить текущее совпадение, сравнивая:
S[i]S[j]Если они равны, то мы можем увеличить длину префикса на единицу:
Иначе мы не можем продлить текущий префикс, поэтому нужно попробовать более короткий.
Следующий кандидат:
Мы повторяем этот процесс, пока:
Если совпадение не найдено, то:
vector<int> prefix_function(string s) {
vector<int> p(s.size());
for (int i = 1; i < (int)s.size(); i++) {
int j = p[i - 1];
while (j > 0 && s[i] != s[j]) {
j = p[j - 1];
}
if (s[i] == s[j]) {
j += 1;
}
p[i] = j;
}
return p;
}