группа strstr'ов
Может, есть ещё какие-то ограничения?
Какая используется библиотека? GNU? BSD? Ещё какая?
---
...Я работаю антинаучным аферистом...
getsuboptНет. У меня задача такая: дан урл, мне надо определить, есть ли в нем "запрещенные" слова. Если есть, то, например, заменить все символы этого подслова на звездочки. Например, так.
![](/images/graemlins/smile.gif)
То, что я написал -- работает, но не очень-то и быстро.
Список слов, надеюсь, не очень часто меняется?
---
...Я работаю антинаучным аферистом...
Будет работать за линейное время от длины проверяемой строки.
Такие есть?
---
...Я работаю антинаучным аферистом...
Бойеру---МуруЯ правильно помню, что это такое описание работы НКА в специфическом случае, придуманное в те времена, когда регексов ещё не было?
Почему "НКА," я только не понял.
---
...Я работаю антинаучным аферистом...
Объяснись.
Ты представляешь вообще что такое конечные автоматы?
---
...Я работаю антинаучным аферистом...
Любой конечный автомат проходит строку за линейное время. Что оптимизировать-то?
>> Почему "НКА," я только не понял.
Потому что в данном конкретном случае можно легко получить 2^(количество слов) состояний ДКА. Это, наверное, не очень прикольно.
БМ, в общем случае, не сравнивает со следующего знака,
неоптимизированный КА такое может делать.
---
...Я работаю антинаучным аферистом...
Вот поэтому и надо оптимизировать.
---
...Я работаю антинаучным аферистом...
А, да, точно. Ты прав.
> Потому что в данном конкретном случае можно легко получить
> 2^(количество слов) состояний ДКА.
> Это, наверное, не очень прикольно.
А можно и не получить.
Если человек захотел скорости, ему где-то придётся
пожертвовать памятью или сложностью.
Если строчки берутся из естественного языка,
число состояний очевидно будет меняться помедленнее.
---
...Я работаю антинаучным аферистом...
Ты понимаешь, что 2n << 2^10 n?Ладно, забей. Хотя мне всё равно интересно, что это ты там написал такое. Если я правильно помню, Б.-М. довольно сложные действия на каждом шаге проделывал, сложнее чем один шаг НКА, зато позволял уменьшить количество шагов до ~n/m (где m - длина искомого слова) (если очень повезёт).
Вот поэтому и надо оптимизировать.
В данном конкретном случае - нахождение нужных слов в урле - регексы являются лучшим возможным решением. В частности ещё и потому, что позволяют без напрягов переходить к более сложным способам задания ключевых слов. Ну и потому, что присоединяются к проекту минут за десять =)
Делать многопроходный БМ или однопроходный офигенный КА?
Многопроходный БМ проще.
---
...Я работаю антинаучным аферистом...
Многопроходный БМ проще.регекс проще. И быстрее, чем многопроходный БМ. И программировать его не надо.
Лично я считаю КА довольно дорогим удовольствием.
Хотя бы потому, что если слов будет много, непонятно,
что он там скомпилирует, будет ли это всё достаточно оптимально.
---
...Я работаю антинаучным аферистом...
Я не очень верю в то, что КА быстрее, оптимизирующих РВ я ещё не видел.
---
...Я работаю антинаучным аферистом...
![](/images/graemlins/smile.gif)
Хочу попробовать, результат доложу.
![](/images/graemlins/smile.gif)
берёшь все эти строки что ищешь и склеиваешь их в БОР - дерево в котором на рёбрах буквы, все слова начинаются в корне а дальше расползаются вниз по дереву.
строишь префикс функцию как в КМП для этого дерева.
и в итоге получается КМП на боре.
http://www.maz.de/parser/1/3.html
А сколько всё-таки получается вершин в ДКА для всего леса?
Кстати, насколько я помню, общий алгоритм преобразования НКА в ДКА всегда выдаёт минимальный ДКА, так что можно не заморачиваться изобретением своего алгоритма для данного конкретного случая, правда?
Вот здесь подробнее: А сколько всё-таки получается вершин в ДКА для всего леса?
Кстати, насколько я помню, общий алгоритм преобразования НКА в ДКА всегда выдаёт минимальный ДКА, так что можно не заморачиваться изобретением своего алгоритма для данного конкретного случая, правда?
вроде очевидно что не больше чем суммарное число букв в искомых строках + 1
на боре просто обратные дуги префикс функции добавляются.
это как раз поиск нескольких подстрок в строке за линейное время
БМ тоже программировать не надо, он точно так же берётся из Сети.Если надо проверить очень много слов, то после преобразования в КА входные строки будут обрабатываться за линейное время - на каждую букву нужно будет совершать пару простейших операций. А в случае с применением многократного поиска подстроки у нас ещё будет множитель M (число проверяемых слов который может быть гораздо больше той оптимизации, которую нам даст оптимизированный БМ, пропускающий буквы. Кстати, эту оптимизацию, скорее всего, можно применить и к КА.
Я не очень верю в то, что КА быстрее, оптимизирующих РВ я ещё не видел.
![](/images/graemlins/smile.gif)
Буду ботать, надо что-то писать, но пока не заботал теорию.
![](/images/graemlins/smile.gif)
надо что-то писать
Не верю, что имеет смысл писать отсебятину, максимум стоит сгенерить что нибудь на ragel-е или типа того.
погугли алгоритм Карасика
Что-то не нашел я никакого Карасика.
![](/images/graemlins/smile.gif)
А вообще, как Карасик на английском пищется хоть? Fish?
![](/images/graemlins/wink.gif)
![](/images/graemlins/smile.gif)
Нужно гуглить по сочетанию Aho-Korasick.
Оставить комментарий
Werdna
Узкое место проги:char *str -- строка
char **substrs -- массив подстрочек
требуется определить, есть ли какая-либо из подстрочек в данной строке.
Как можно заоптимизировать код? Фактически, хочется получить аналог "группового strstr", но как лучше реализовать -- не знаю.
any ideas?