Эффективный способ получить ключ от значения, когда карта содержит вектор строки в качестве значения - PullRequest
0 голосов
/ 27 сентября 2018

Как получить ключ, используя значение, которое является вектором строки и наоборот.Ниже приведен мой код.

#include<iostream>
#include<map>
#include<string>
#include <unordered_map>
#include <vector>

using namespace std;
int main()
{
std::unordered_map<std::string, std::vector<std::string>> Mymap;
Mymap["unique1"] = {"hello", "world"};
Mymap["unique2"] = {"goodbye", "goodmorning", "world"};
Mymap["unique3"] = {"sun", "mon", "tue"};

for(auto && pair : Mymap) {
        for(auto && value : pair.second) {
                std::cout << pair.first<<" " << value<<"\n";
                if(value == "goodmorning") // how get key i.e unique2 ?
        }}
}

case 1: Когда вводится значение.клавиша выводится.

Input  : goodmorning
output : unique2

case 2: Когда клавиша вводится, выводится значение.

Input : unique3
output: sun ,mon ,tue

Примечание: библиотека буста недоступна.

Ответы [ 3 ]

0 голосов
/ 27 сентября 2018

Для случая 1 комбинация find_if и any_of сделает работу.

Для случая 2 вы можете просто использовать find метод unordered_map.

#include<iostream>
#include<map>
#include<string>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    unordered_map<string, vector<string>> Mymap;
    Mymap["unique1"] = { "hello", "world" };
    Mymap["unique2"] = { "goodbye", "goodmorning", "world" };
    Mymap["unique3"] = { "sun", "mon", "tue" };

    // Case 1

    string test_value = "goodmorning";
    auto iter1 = find_if(Mymap.begin(), Mymap.end(),
        [&test_value](const decltype(*Mymap.begin()) &pair)
        {
            return any_of(pair.second.begin(), pair.second.end(), [&test_value](const string& str) { return str == test_value; });
        });

    if (iter1 != Mymap.end())
    {
        cout << "Key: " << iter1->first << endl;
    }
    else
    {
        cout << "No key found for " << test_value;
    }

    // Case 2

    test_value = "unique3";
    auto iter2 = Mymap.find(test_value);
    if (iter2 != Mymap.end())
    {
        int first = true;
        for (auto v : iter2->second)
        {
            cout << (first ? "" : ", ") << v;
            first = false;
        }
        cout << endl;
    }
    else
    {
        cout << "No value found for key " << test_value << endl;
    }

    return 0;
}
0 голосов
/ 27 сентября 2018

Создать другую карту, идущую по-другому для каждой записи вектора?

Если записи массива не уникальны, вам нужно будет сделать то же самое преобразование карты в вектор или использовать multimap.

Также рассмотрите возможность использования хэш-карты (unordered_map) и просмотра строк в качестве способа сокращения использования памяти второй картой?

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

0 голосов
/ 27 сентября 2018

Ключ хранится в pair.first.Просто используйте это, если ваш сценарий использования находится в итерации цикла, как вы иллюстрировали.

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

...