Изменения
→Оптимизация
Внесем несколько важных замечаний:
*<tex>\pi(i + 1)</tex> превосходит <tex>pi(i)</tex> не больше чем на <tex>1</tex>. Действительно, если <tex>\pi(i+1) > \pi(i) + 1</tex>, тогда <tex>\pi(i+1) - 1 > \pi(i)</tex>, получили противоречие.
*Избавимся от явных сравнений строк. Пусть мы вычислили <tex>\pi(i)</tex> и <tex>s[\pi(i) + 1] = s[i + 1]</tex>, тогда очевидно <tex>\pi(i+1) = \pi(i) + 1</tex>. Если же условие <tex>s[\pi(i) + 1] = s[i + 1]</tex> ложно, то хотелось бы найти наибольшую длину <tex> j</tex>, для которой верно <tex>\pi(i+1) = j + 1</tex>. Когда мы найдем такое <tex>j</tex> нам достаточно будет сравнить <tex>s[j + 1]</tex> и <tex>s[i + 1]</tex>, при их равенстве <tex>\pi(i+1) = j + 1</tex> будет верно. Будем искать наше <tex>j</tex> пока оно больше нуля, при равенстве нулю <tex>\pi(i+1) = 01</tex>, если <tex>s[i] = s[1]</tex>, иначе нулю. Общая схема алгоритма у нас есть, теперь нужно только научиться искать <tex>j</tex>.*Для поиска <tex>j</tex> нам стоит использовать равенство <tex>j = \pi(j)</tex>, когда <tex>s[j+1] = s[i+1]</tex> ложно, взяв за исходное <tex> j = \pi(i)</tex>, это позволит выбирать <tex>j</tex> по убыванию вплоть до нуля, так как очевидно, что <tex>\pi(x) \geq \pi(\pi(x))</tex>.
===Псевдокод===
'''Prefix_function''' (<tex>s</tex>)