Один из видов быстрого и эффективного алгоритма поиска для некоторых случаев - это тот, который (если искомые данные не меняются, и вы просто выполняете поиск снова и снова по одному и тому же содержимому буфера) выполняет поиск один раз и создает некую поисковую таблицу.,Одним из возможных решений является BoyerMoore (см. Ссылку в комментарии Руди), но, поскольку это не очень хорошо работает для символов Юникода с действительно высоким диапазоном (скажем, диапазон $ 0000 ... $ FFFF), оно все равно было быстрее, чем повторные вызовы Pos или SearchBuf,но он потреблял много памяти, когда я тестировал его с действительно расширенными наборами данных Unicode (например, китайский текст).Мое мнение, что нет никакого решения "slam dunk".
Возможно, вы могли бы написать более быстрое решение, чем Pos-но-не-так-много-как-память-как-BoyerMoore, например:
Создать таблицу длявсе точки персонажа и сохраните первое место, где появляется каждый символ.Я бы использовал разреженный отсортированный массив, для каждого выполненного вами поиска сохраняйте каждое начальное местоположение для этого начального символа.Это избавит вас от поиска методом грубой силы по большой строке в юникоде, которая ищет начальные совпадения символов.
Если в таблице нет записи для конкретного символа, вам нужно выполнить грубую силупоиск (только один раз), чтобы создать эти данные настройки.Если вы выполняете поиск один раз методом грубой силы, а кодовая точка U + 1234 не появляется, тогда запись для U + 1234 должна быть пустым массивом []
, указывающим, что вам не нужно искать снова, и может быстро потерпеть неудачу при поискеначальный символ не совпадает.
После того, как вы нашли непустой список поиска начальных символов, например, [123,456,789]
, начальное совпадение кодовой точки, вы можете продолжить сделать посимвольную проверку в строке [123 ... x], затем в строке [456..x] и так далее, пока у вас не закончатся элементы в массиве.Любое несоответствие вызывает переход к следующему элементу в таблице поиска.
Опять будут патологические случаи, когда вся эта дополнительная работа приводит к тому, что код работает менее быстро, чем Pos, иесли вы не уверены, что вам нужно искать множество разных подстрок в одной и той же большой строке, то все эти «оптимизации» - пустая трата времени;Забудьте об этом, даже поиск строк Бойера-Мура выполняется медленнее, когда вы не можете повторно использовать таблицу данных поиска по крайней мере несколько раз.
Если все, что вам нужно, это функция Pos (), которая оптимизируется вручную в Assembly дляработать настолько быстро, насколько это возможно в рамках библиотечной функции, которая не создает и не потребляет хранилища промежуточных таблиц, тогда, поздравляю, Pos () уже, вероятно, работает настолько быстро, насколько вы можете (я полагаю, это было оптимизировано FastCodeлюди несколько лет назад).