Самый быстрый подход к расширению запросов фраз

Я использую список синонимов, чтобы направлять процесс расширения запроса. Формат выглядит так:

fu=foo
ba=bar
etc=etcetera
werd=word

Я использую простой алгоритм двоичного поиска для запуска каждого из слов пользовательского ввода в этом списке. Проблема в том, что когда речь идет об использовании фраз.

    quick brown fox=alphabet
    out of this world=space
    why hello there=hello

Типичный ввод: why hello there, where can I get an out of this world hopper?

И желаемый результат: hello, where can I get an space hopper?

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

Поэтому я ищу способы запустить бинарный поиск по фразам или построить тезаурус таким образом, чтобы компенсировать фразы.

Я использую PHP для этого. Любые предложения приветствуются.

3 ответа

Решение

Простой подход будет использовать str_replace. Я не знаю о спектакле, хотя.

$list = array('out of this world' => 'space');
$str = 'why hello there, where can I get an out of this world hopper?';

foreach ($list as $old => $new) {
    $str = str_replace($old, $new, $str);
}

Редактировать: я часто замечал, что более эффективно использовать встроенные функции вместо написания собственных, потому что встроенные модули уже скомпилированы, но ваш оптимизированный алгоритм должен интерпретироваться, что является огромным замедлением.

Использование preg_replace_callback вместо того, что вы сделали сейчас. PCRE оказывается достаточно эффективным при поиске строк, потому что это то, для чего он был создан.

Вам просто нужно создать единый список альтернатив, а затем выполнить фактическую замену через исходную карту / словарь в обратном вызове.

$phrases = array(...);

$rx = implode("|", array_keys($phrases));
$text = preg_replace("/\b($rx)\b/musie", '$phrases["\1"]', $text);

Просто используя /e Выражение здесь, обратный вызов может быть более полезным.

Моей первой идеей было бы использовать ассоциативный массив, подобный этому

$thesaurus = array(
   'alphabet'  => 'quick brown fox',
   'space'     => 'out of this world',
   'hello'     => 'why hello there'
);

Таким образом, вы можете использовать встроенные функции array_search, которые будут работать быстрее, чем все, что вы могли бы написать на PHP (я думаю).

Другие вопросы по тегам