Задать вопрос

Как найти вхождения сотен поисковых фраз в большом тексте (PHP, MySQL)?

Дано:

1) Художественный текст размером до 10 мегабайт.
2) Список поисковых фраз (фразы состоят из разного количества слов), который будет пополнятся. Счет идет на сотни фраз.

Необходимо:

1) Найти все вхождения поисковых фраз в тексте.
2) Подсветить вхождения.

В наличии Mysql и PHP. У меня такие вопросы:

1) Как к этой задаче подступиться? Какой способ поиска будет оптимальным?
2) Потянет ли рядовой виртуальный хостинг выполнение такой задачи хотя бы одним пользователем одновременно без нареканий хостера?
  • Вопрос задан
  • 4458 просмотров
Подписаться 4 Оценить 2 комментария
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 1
Сложного ничего не вижу. Как то давно, тоже надо было найти в большом тексте (около 15 мб) пару фраз.
1) Поиск осуществлять strpos, начиная с последней найденной позиции. Таким образом Вы получите позиции вхождения фраз в текст - тогда не будет проблем с подсветкой.
2) Если фразы будут добавляться, а текст при этом останется исходным, я бы сделал обработку один раз, сохранил для каждой фразы точки вхождения и при дальнейшей обработке просто добавлял бы новые фразы, искал бы по ним вхождения и сохранял. Это позволит Вам сэкономить ресурсы и раздавать результат большому количеству пользователей.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
ScorpLeX
@ScorpLeX
Если стоит задача не вызвать нареканий хостера, нужно делать очередь, разбивать и ставить текст в очередь на обработку.
Если имеется только mysql и php в принципе нет особой разницы как искать, только нужно понимать, что в алгоритм желательно заложить например usleep дабы не создавать скачки загрузки cpu.
Ответ написан
@klirichek
В принципе, можно попробовать сделать в один проход.
Для каждой фразы делаем ДКА состояний - чтоб ловить поступающие слова и двигать состояние вперёд, если совпадает с ожидающим следующим словом. Если слова закончились - запоминать найденную позицию и сбрасывать состояние. Если новое слово не совпадает - просто сбрасывать состояние.
А дальше - организуем "игру в лото". Проходимся один раз по тексту от начала до конца и "объявляем" всем участвующим ДКА каждое слово. В конце залезаем в них и получаем списки "выигравших" позиций для каждой фразы.
Это в общем. А дальше можно оптимизировать - например, сравнивать не слова, а хэшики от них.
И не "объявлять" каждому "игроку" каждое слово, а собирать у них множество ожидаемых ими хэшиков - и если текущий попадает в множество - двигать состояния у "выигравших", а у всех остальных - сбрасывать.
Ещё шаг - сделать не одно, а два множества. В одном - хэшики тех, что в начальном состоянии (при сбросе они не меняются -> не нужно читать значения заново). Во втором - "играющие".

Здесь нужно побенчить по сравнению с indexof. Последний внутри себя, конечно, будет работать быстрее, чем аналогичный "самописный", однако на определённых параметрах (совокупность размера входного текста вместе с количеством и размером искомых фраз) уже может вполне его обойти за счёт меньшей сложности.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽