Изменения

Перейти к: навигация, поиск
Нет описания правки
На самом деле нам не обязательно сравнивать всю искомую строку с элементами суффиксного массива. На каждой итерации бинарного поиска мы уточняем некий диапазон, внутри которого может находиться искомый элемент. Все строки в таком диапазоне в некотором смысле похожи. А именно, у данных строк может быть общий префикс с искомой строкой, так как у тех, что остались вне диапазона, общего префикса уж точно не будет (в том смысле, что мы не рассматриваем уже обработанную часть образца как часть префикса). <br>
<br>
Пусть границы нашего диапазона на каком-то шаге - это <tex> L </tex> и <tex> R </tex>. Допустим мы знаем длину общего префикса образца с краями текущего диапазона: <tex> l </tex> - общий префикс образца и левого края, <tex> r </tex> - общий префикс образца и правого края, где <tex> l = lcp(p, array[L]) </tex>, <tex> r = lcp(p, array[R]) </tex> (lcp - longest common prefix). Будем поддерживать <tex> l </tex> и <tex> r </tex> после каждого уточнения границ диапазона. Тогда справедливо сделать пару утверждений. <br>
Первое утверждение заключается в том, что для любой строки внутри диапазона lcp не меньше, чем минимум из <tex> l </tex> и <tex> r </tex>. Если бы это было не так, то значит при неизменной начальной части префикса была бы позиция, где символ сначала совпадал бы с соответствующим символом образца, потом не совпадал, а потом снова совпадал. Это противоречило бы отсортированности диапазона. Важно хорошо проникнуться этой идеей, так как дальше мы ее будем использовать как нечто само собой разумеющееся.<br> Второе утверждение очевидно: если общий префикс образца и любой строки внутри диапазона не меньше <tex> m = min(l,r) </tex>, то <tex> m </tex> символов можно пропускать сразу, зная, что они совпадают в любом случае, и сравнивать только начиная с <tex> m + 1 </tex> символа.
Пусть границы нашего диапазона на каком-то шаге - это L и R. Допустим мы знаем длину общего префикса образца с краями текущего диапазона: l - общий префикс образца и левого края, r - общий префикс образца и правого края, где l = lcp(p, array[L]), r = lcp(p, array[R]) (lcp - longest common prefix). Тогда справедливо сделать пару утверждений. <br>Первое утверждение заключается в том, что для любой строки внутри диапазона lcp не меньше, чем минимум из l и r. Если бы это было не так, то значит при неизменной начальной части префикса была бы позиция, где символ сначала совпадал бы с соответствующим символом образца, потом не совпадал, а потом снова совпадал. Это противоречило бы отсортированности диапазона. Важно хорошо проникнуться этой идеей, так как дальше мы ее будем использовать как нечто само собой разумеющееся. Второе утверждение очевидноФайл: если общий префикс образца и любой строки внутри диапазона не меньше m = min(l,r), то m символов можно пропускать сразу, зная, что они совпадают в любом случае, и сравнивать только начиная с m + 1 символаpic.png|450px]]
[[ФайлТаким образом мы применим оптимизированное сравнение строк в бинарном поиске строки «в лоб». В худшем случае, конечно, ничего мы от этого не выиграем:picесли искомый элемент находится на краю массива, но соседи совсем не похожи по <tex> lcp </tex>, то <tex> r </tex> (или <tex> l </tex>) будет мало каждый раз, <tex> m </tex> будет тоже мало, что сведет оптимизацию на нет.pngТаким образом в наихудшем случае результат будет прежним <tex> O(|450px]]p|ln|s|) </tex>, но в среднем <tex> O(|p| + ln|s|) </tex>.
271
правка

Навигация