как мне эффективно искать до и после элемента для ключевой фразы

0

У меня очень большой набор данных (от 100 000 элементов до 250 000 элементов), которые я сейчас храню в векторе с целью поиска набора слов. Учитывая фразу (например, "on, para"), функция должна найти все слова, начинающиеся с данной фразы, и нажимать все совпадения в очереди.

Чтобы найти начальное слово, я использую двоичный поиск, который, кажется, отлично работает, но после того, как начальное слово найдено, я застреваю. Как я должен эффективно выполнять итерацию до и после элемента, чтобы найти все подобные слова? Вход в алфавитном порядке, поэтому я знаю, что все другие возможные совпадения будут происходить до или после возвращения элемента. Я чувствую, что должна быть функция, возможно, <algorithm> которой я мог бы воспользоваться. Вот часть соответствующего кода:

Функция двоичного поиска:

int search(std::vector<std::string>& dict, std::string in)
{
    //for each element in the input vector
    //find all possible word matches and push onto the queue
    int first=0, last= dict.size() -1;
    while(first <= last)
    {
        int middle = (first+last)/2;
        std::string sub = (dict.at(middle)).substr(0,in.length());
        int comp = in.compare(sub);
        //if comp returns 0(found word matching case)
        if(comp == 0) {
            return middle;
        }
        //if not, take top half
        else if (comp > 0)
            first = middle + 1;
        //else go with the lower half
        else
            last = middle - 1;
    }
    //word not found... return failure
    return -1;
}

В main()

//for each element in our "find word" vector
for (int i = 0; i < input.size()-1; i++)
{
    // currently just finds initial word and displays
    int key = search(dictionary, input.at(i));
    std::cout << "search found " << dictionary.at(key) <<
                 "at key location " << key << std::endl;
}
Теги:
vector
search
stl

3 ответа

1
Лучший ответ

std :: lower_bound и итерация вперед (вы также можете использовать std :: upper_bound):

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
    typedef std::vector<std::string> Dictionary;
    Dictionary dictionary = {
        "A", "AA", "B", "BB", "C", "CC"
    };
    std::string prefix("B");
    Dictionary::const_iterator pos = std::lower_bound(
        dictionary.begin(),
        dictionary.end(),
        prefix);
    for( ; pos != dictionary.end(); ++pos) {
        if(pos->compare(0, prefix.size(), prefix) == 0) {
            std::cout << "Match: " << *pos << std::endl;
        }
        else break;
    }
    return 0;
}
  • 0
    это будет быстрее, чем бинарный поиск, а затем итерация? Цель программы - максимально быстрое выполнение
0

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

  • Хэш/Карта. Вы можете хранить свои предметы как хэш/карту и иметь очень быстрый поиск, но поиск следующего и предыдущего проблем.
  • Двоичное дерево /N-арное дерево /B-дерево - очень хорошая динамическая производительность вставки/удаления, а также хорошие времена поиска, и дерево упорядочено, поэтому поиск следующего/предыдущего стабилен.
  • Фильтр цветка - иногда все, что вы хотите сделать, это проверить, находится ли элемент в вашей коллекции, а фильтр цветка имеет очень низкий ложноположительный, поэтому это хороший выбор.

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

0

Вам нужно было создать индекс не для каждой фразы, а для любой подфраки. началось с слова. Например, для dict-string "New York" вы должны сохранить индекс для двух строк: "Нью-Йорк" и "Йорк". См. Мою демоверсию автозаполнения, которая иллюстрирует эту идею:

http://olegh.cc.st/autocomplete.html

Как вы видите, эта подсистема быстро работает со словарями, большей, чем ваши 250K элементов. Конечно, я не использую бинарный поиск, поскольку он медленный. Вместо этого я использую хеширование.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню