Сопоставление текста Aho-Corasick по целым словам?

Я использую сопоставление текста Aho-Corasick и задаюсь вопросом, можно ли его изменить, чтобы он соответствовал условиям вместо символов. Другими словами, я хочу, чтобы в основе сопоставления лежали термины, а не символы. Например:

Поисковый запрос: «Он»,

Предложение: «Привет, мир»,

Aho-Corasick сопоставит «он» с предложением «привет, мир», оканчивающимся на индекс 2, но я бы предпочел, чтобы совпадений не было. Итак, под «терминами» я подразумеваю слова, а не символы.


person DotNet    schedule 21.01.2013    source источник
comment
Что вы подразумеваете под терминами? Можете ли вы привести пример?   -  person templatetypedef    schedule 21.01.2013


Ответы (4)


Один из способов сделать это — использовать Aho-Corasick как обычно, а затем выполнить шаг фильтрации, исключающий все ложные срабатывания. Например, каждый раз, когда вы находите совпадение, вы можете подтвердить, что следующий и предыдущий символы во входных данных являются небуквенными символами, такими как пробелы или знаки препинания. Таким образом, вы получаете скорость поиска Ахо-Корасика, но учитываете только те совпадения, которые появляются в тексте как целые слова.

Надеюсь это поможет!

person templatetypedef    schedule 21.01.2013

Одной из возможностей может быть включение символа пробела в ваш поисковый запрос, возможно, после предварительной обработки вашего ввода для преобразования всех видов пробелов (пробел, перевод строки, возврат каретки, табуляция...) в один и тот же символ пробела.

Другой возможностью было бы думать о символах вашего алфавита, насколько это касается Ахо-Корасика, как о словах. Aho-Corasick будет работать так же быстро (если не быстрее) с алфавитом размера 2^32, где каждое слово во входном тексте кодируется как отдельный символ, как и с алфавитом размера 2^8, где символ, как обычно, состоит из одного байта.

В любом случае вы должны принять решение о том, что ваша предварительная обработка делает с пунктуацией.

person mcdowella    schedule 21.01.2013

Если вы используете метод onlyWholewords(), он не должен дать никаких результатов для вашего примера выше. Например:

Trie trie = Trie.builder()
             .onlyWholeWords()
             .addKeyword("He")
             .build();
Collection<Emit> emits = trie.parseText("Hello World");

emits в этом случае будет пустым.

Это приведет только к целым словам только о том, что он.

Хотя остерегайтесь символов, которые не являются [a-z A-Z]. например, если вы:

"He//Is" 

Он подберет He и проигнорирует //

Две вещи, чтобы добавить:

  1. если вы хотите установить границу слова, вы можете использовать:

    onlyWholeWordsWhiteSpaceSeparated() вместо

    только целые слова ()

  2. Если вы хотите добавить некоторых персонажей в белый список, это чтение может оказаться полезным:

Используемые символы слова являются символами по умолчанию, измененными предоставленными, а логические флаги сигнализируют, где символы включаются и выключаются. Это полезно, когда вы просто хотите отключить определенный символ в наборе символов по умолчанию. Например:

Используемые символы слова являются символами по умолчанию, измененными предоставленными, а логические флаги сигнализируют, где символы включаются и выключаются. Это полезно, когда вы просто хотите отключить определенный символ в наборе символов по умолчанию. Например:

новый WholeWordMatchSet (ключевые слова, правда, ['_', '='], [ложь, правда])

Создаст набор, в котором буквы и цифры, а также - и = считаются символами слова, но не _.

person HBizzle    schedule 11.10.2020

Очень поздно для вечеринки, но есть еще один вариант — вставить в древовидную структуру несколько символов, представляющих начало и конец слов. Затем, на этапе сопоставления, они должны совпасть соответствующим образом. Сам собираюсь попробовать такой подход.

person Edward Falk    schedule 28.10.2019