Ответ 1
Что делает функция canonize
, это то, что описано в самом конце этого сообщения SA, где мы рассматриваем такую ситуацию:
Ситуация такова:
-
Активная точка находится в
(red,'d',3)
, т.е. три символа в краюdefg
, выходящем из красного node. -
Теперь мы следуем ссылке суффикса на зеленый node. Теоретически, наш активный node теперь
(green,'d',3)
. -
К сожалению, эта точка не существует, потому что край
de
, выходящий из зеленого node, имеет только 2 символа. Следовательно, мы применяем функциюcanonize
.
Он работает следующим образом:
-
Начальный характер интересующего нас ребра
d
. Этот символ упоминается как t k в обозначении Ukkonen. Итак, "поиск t k -edge" означает поиск краяde
на зеленом node. -
Этот край имеет длину всего два символа. То есть
(p' - k') == 2
в обозначениях Укконена. Но исходный край имел три символа:(p - k) == 3
. Итак,<=
истинно, и мы вводим цикл. -
Мы сокращаем ребро, которое мы ищем, от
def
доf
. Это то, что делает шагp := p + (k' - p') + 1
. -
Мы переходим в состояние, на которое указывает ребро
de
, т.е. голубое состояние. Это то, что делаетs := s'
. -
Так как оставшаяся часть
f
края не пуста (k <= p
), мы идентифицируем соответствующий выходящий край (то есть крайfg
, выходящий из синего node). Этот шаг устанавливает k 'и p' в совершенно новые значения, поскольку теперь они относятся к строкеfg
, а ее длина (p '- k') теперь будет равна 2. -
Длина оставшегося ребра
f
, (p - k) теперь равна 1, а длина края-кандидатаfg
для новой активной точки (p '- k'), равно 2. Следовательно, условие циклаwhile (p '- k') <= (p - k) do
перестает быть истинным, поэтому цикл заканчивается, и действительно, новая (и правильная) активная точка (blue,'f',1)
.
[На самом деле, в обозначениях Укконена конечный указатель р ребра указывает на положение конечного символа ребра, а не на следующую позицию. Следовательно, строго говоря, (p - k) равно 0, а не 1, а (p '- k') равно 1, а не 2. Но важно не абсолютное значение длины, а относительное сравнение двух разных длина.]
Несколько заключительных заметок:
-
Указатели, такие как p и k, ссылаются на позиции в исходном тексте ввода t. Это может быть довольно запутанным. Например, указатели, используемые в краю
de
на зеленом node, будут ссылаться на некоторую подстрокуde
для t, а указатели, используемые в краюfg
на синем node, будут ссылаться на некоторую подстрокуfg
t. Хотя строкаdefg
должна отображаться как одна непрерывная строка где-то в t, подстрокаfg
может отображаться и в других местах. Таким образом, указатель k краяfg
не обязательно конечный указатель p краяde
плюс один. -
Что считается, когда мы решаем, следует ли закончить цикл, это не абсолютные позиции k или p, а длина (p - k) оставшегося ребра по сравнению с длиной (p '- k' ) текущего края-кандидата.
-
В вашем вопросе, строка 4 фрагмента кода, есть опечатка: она должна быть
k'
вместоk;
.