Как найти подстроку в строке в мультикарте - PullRequest
0 голосов
/ 27 января 2020

Как найти подстроку в строке в ключе мультикарты? Например, если я введу «Луи», то будут найдены Луисвилл, Луисберг и Сент-Луис?

Ответы [ 2 ]

0 голосов
/ 30 января 2020

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

Вы можете использовать std::find_if и предоставить функцию предиката для сопоставления элементов и повторения вашей карты , Я использую std::map в приведенном ниже коде, но это может относиться и к std::multimap.

#include <map>
#include <string>
#include <algorithm>
#include <iostream>

int main()
{
    std::map<std::string, std::string> myMap{
        {"Louis", "AA"}, {"Louisville", "BBB"}, {"Louisberg", "A"},
        {"StLouis ", "C"}, {"Huntsville", "D"} };

    std::string term("Louis");

    auto keyContains = [&term](const std::pair<std::string, std::string>& item)
    {
        return item.first.find(term) != std::string::npos;
    };

    auto iter = std::find_if(myMap.begin(), myMap.end(), keyContains);

    while (iter != myMap.end())
    {
        std::cout << iter->first << std::endl;
        iter = std::find_if(std::next(iter), myMap.end(), keyContains);
    }
}

keyContains - это лямбда-функция. Если вы не знакомы с лямбда-функциями, вы можете использовать вместо этого функтор:

struct keyContains
{
    keyContains(const std::string& searchTerm) : mSearchTerm(searchTerm) {}

    bool operator() (const std::pair<std::string, string>& item) const
    {
        return item.first.find(mSearchTerm) != std::string::npos;
    }

    std::string mSearchTerm;
};

Затем инициализируйте его следующим образом: keyContains comp("Louis") и передайте comp в качестве предиката.

Надежда это полезно? Это эффективно для l oop, который ходит по карте. Рабочая версия здесь .

Обновление:

Я только что прочитал ваш комментарий, где вы сказали, что ваш поиск должен возвращать 54049 результатов , Это много записей! Для этого лучше сопоставить префикс или суффикс. Вы можете использовать std::map::lower_bound() и std::map::upper_bound().

0 голосов
/ 27 января 2020

Зачем беспокоиться о мультикарте для этого?

std::string search_term = "Louis";
std::unordered_set<std::string> data = { "Louisville", "Louisberg", "StLouis" };
for (std::string const& each : data) {
    if (std::find(each.begin(), each.end(), search_term) != std::string::npos) { 
        // contains it
    } 
}

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

...