Хорошо, предложу ещё один метод, попроще КА и побыстрее сравнения списка подстрок.
Постулат: ищем только русские слова, из алфавита 31 буквы (е и ё можно безопасно объединить в одну, ну и знаки ъ и ь тоже) плюс пустой заполнитель.
Для представления символа алфавита достаточно 5 битов, для представления 5-ти первых букв слова достаточно 25 битов.
Заводим массив из
битов, это всего 4 мегабайта, биты устанавливаем в 1 если эти 5 букв являются началом какого-то слова в словаре искомых (здесь и нужен пустой заполнитель для учёта слов короче пяти букв).
После этого для каждого символа входного потока проверяем последние полученные 5 символов входного потока как 25-ти битный указатель в массив и если там нулевой бит - в этой позиции (точнее конечно 5 символов назад) искомых слов не начинается. Сложность линейная по размеру текста и константная по размеру словаря искомых строк.
Конечно если бит равен единице, то надо проверять дальше, но и это можно оптимизировать, например задать массив указателей на списки слов для любых комбинаций первых трёх символов, это всего
указателей, 256 килобайт обычно (ну или из 4-х букв, это
указателей, обычно 4 мегабайта), в каждом таком списке слов будет уже далеко не 4000, а всего с десяток-два, их проверить уже быстро. Можно конечно и вообще отказаться от битового массива и проверять по три символа прямо по массиву указателей, но это будет немного медленнее из-за большего количества ложных срабатываний, приводящих к проверке списка слов (хоть он и на два порядка короче, но всё же).
Да, по видимому от пустого заполнителя можно отказаться и знаки ъ и ь не объединять, все короткие слова (менее 3-х или 4-х букв) всё равно попадут в списки.
Фактически это простейший вариант хэштаблиц.
-- 22.01.2018, 20:43 --Дык, вот пожалуйста
Наверное я отупел спросонья, но не вижу в моих словах сравнений двух регэспов, вижу только сравнение регэспа и тривиального сравнения подстрок.