Два рядки довжиною k , що відрізняються одним символом, мають префікс довжиною l і суфіксом довжини m таким, що k = l + m + 1 .
Відповідь на Simon Прінса кодує це шляхом збереження всіх префікса / суфікса комбінації в явному вигляді, тобто abc
стає *bc
, a*c
і ab*
. Це k = 3, l = 0,1,2 і m = 2,1,0.
Як вказує valarMorghulis, ви можете впорядкувати слова в дереві префіксів. Є також дуже схоже дерево суфіксів. Доповнити дерево досить просто, кількість листкових вузлів під кожним префіксом або суфіксом; це можна оновити в O (k), вставляючи нове слово.
Причина, за якою ви хочете, щоб ці підрахунки брати побратимів, - це те, що ви знаєте, давши нове слово, чи потрібно перераховувати всі рядки з тим самим префіксом, чи перераховувати всі рядки тим самим суфіксом. Наприклад, для "abc" як вхідних даних, можливі префікси "", "a" та "ab", тоді як відповідні суфікси - "bc", "c" та "". Як очевидно, для коротких суфіксів краще перераховувати братів і сестер у префіксному дереві та навпаки.
Як зазначає @einpoklum, безумовно, можливо, що всі рядки мають однаковий префікс k / 2 . Це не проблема для цього підходу; дерево префікса буде лінійним до глибини k / 2, при цьому кожен вузол до k / 2 глибини буде родоначальником 100 000 листових вузлів. Як результат, дерево суфіксів буде використано до (k / 2-1) глибини, що добре, оскільки рядки повинні відрізнятися за суфіксами, враховуючи, що вони мають спільні префікси.
[редагувати] Як оптимізація, як тільки ви визначили найкоротший унікальний префікс рядка, ви знаєте, що якщо є один інший символ, він повинен бути останнім символом префікса, і ви знайшли б майже дублікат, коли перевірка префікса, який був на один коротший. Отже, якщо "abcde" має найкоротший унікальний префікс "abc", це означає, що є й інші рядки, які починаються з "ab?" але не з "abc". Тобто, якби вони відрізнялися лише одним символом, це був би той третій символ. Вам більше не потрібно перевіряти "abc? E".
За тією ж логікою, якщо ви виявите, що "cde" є унікальним найкоротшим суфіксом, то ви знаєте, що вам потрібно перевірити лише префікс довжини-2 "ab", а не довжину 1 або 3 префікса.
Зауважте, що цей метод працює лише для рівно однієї різниці символів і не узагальнює до 2-х відмінностей символів, він покладається на один один символ як розділення між однаковими префіксами та однаковими суфіксами.