Алгоритм поиска паттерна в неупорядоченной последовательности?

Приветствую всех.
Задача такова: есть не отсортированный (естественно) массив байтов размерностью 2млд и более.
Есть определенный паттерн размером в 10 байтов. Надо найти все позиции паттерна в массиве.
Линейный поиск не самая лучшая реализация. Подскажите, что работает быстрее.
Спасибо!
  • Вопрос задан
  • 915 просмотров
Решения вопроса 3
x67
@x67
Ну в общем-то, как заметил Александр, вы хотите чуда, но алгоритм можно оптимизировать, если есть какая-либо закономерность, которая позволяет предсказать, в каких областях может быть искомый паттерн.
Также если местоположение начала паттерна не может быть произвольным (то есть паттерн может начинаться в 1, 11, 21 байте, но не может начинаться в 37 к примеру), то время поиска можно сократить менее, чем в 10 раз, сначала поискав все первые байты, а потом проверив эти места уже полностью.
Также можно поискать закономерность в этом паттерне.
Но в целом, если это будет регулярной задачей, прикрутите что-нибудь для первоначальной обработки массива.
Ответ написан
@fireSparrow
С учётом вашего комментария к ответу x67:
В этом случае можно попробовать проверять только каждый пятый байт. Если там ноль - от него шагаем по одному символу влево до тех пор пока не наткнёмся на не ноль. После чего отходим ещё на пару символов влево и уже с этого символа проверяем вхождение паттерна.
Теоретически можно получить экономию почти в пять раз.
Но это будет хорошо работать только если в массиве мало нулей, не являющихся частью паттерна. Если же в массиве много посторонних нулей - то может получится даже хуже, чем при линейном поиске.
И всё-таки рекомендую попробовать реализовать этот вариант и замерить время работы по сравнению с линейным поиском.
Ответ написан
Комментировать
@Maddox Автор вопроса
Спасибо Александр и x67 Реализовал вашу идею. Вот небольшой отчет производительности на массиве данных размером чуть меньше 1 000 000 запущенный 1000 раз. Время указываю суммарное, за все 1000 запусков.
Линейный поиск - 9000-9300 мс
Реализация Александр - 4100-3900 мс
Доработка (с предварительной проверкой на хотя бы один 0 вокруг buffer[i]) - 3100-2900 мс
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы