304
правки
Изменения
→Оптимизация
*Следует заметить, что <tex>\pi(i) \le \pi(i-1) + 1</tex>. Действительно, если <tex>\pi(i) > \pi(i-1) + 1</tex>, тогда <tex>\pi(i) - 1 > \pi(i-1)</tex>, значит в <tex>\pi(i-1)</tex> не максимально возможное значение, получено противоречие.
*Нужно избавиться от явных сравнений строк. Пусть вычислено <tex>\pi(i-1)</tex> и <tex>s[\pi(i-1) + 1] = s[i]</tex>, тогда <tex>\pi(i) = \pi(i-1) + 1</tex>. Если <tex>s[\pi(i) + 1] </tex> отличается от <tex>s[i + 1]</tex>, то нужно найти наибольшую длину <tex> k</tex>, для которой верно <tex>\pi(i) = k + 1</tex>. Когда найдется такое <tex>k</tex> достаточно будет сравнить <tex>s[k + 1]</tex> и <tex>s[i]</tex>, при их равенстве <tex>\pi(i) = k + 1</tex> будет верно. Итеративно продолжается поиск <tex>k</tex>, пока оно больше нуля. Если <tex>k=0</tex>, то при <tex>s[i] = s[1]</tex> значение <tex>\pi(i)=1</tex> , иначе нулю. Общая схема алгоритма есть, теперь нужно научиться искать <tex>k</tex>.
*За исходное <tex>k</tex> нужно взять <tex>\pi(i - 1)</tex>, что следует из первого пункта. Как видно из рисунка, приведенного ниже, при совпадении символов <tex>s[k + 1]</tex> и <tex>s[i]</tex> длина наибольшего общего префикса увеличивается на единицу. В случае, когда символы <tex>s[k+1]</tex> и <tex>s[i]</tex> не совпадают, <tex>\pi(k)</tex> {{---}} следующая по максимальности длина потенциального наибольшего общего префикса, что тоже понятно из рисунка. Последнее утверждение продолжается по индукцииверно, и получается требуемый поиск пока <tex>k>0</tex>, что позволит всегда найти его следующее значение.
[[Файл:Prefix2.jpg]]