Карта C ++ с вектором в качестве ключа. Как сделать так, чтобы векторный порядок не имел значения? - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть карта, в которой в качестве ключа взят вектор целых. Я инициализирую карту ключом-вектором значений {1, 2, 3}

typedef std::map<std::vector<int>, std::string> VectorMap;
VectorMap vectorMap;
vectorMap[std::vector<int>{1, 2, 3}] = "test";

Затем я использую метод подсчета, чтобы показать, можно ли найти запись в VectorMap, используя вектор {1, 2, 3} в качестве ключа.

std::cout << "count: " << vectorMap.count(std::vector<int>{1, 2, 3}) << std::endl;

Возвращает правильный счет.

count: 1

Однако я хочу сделать так, чтобы порядок значений в вектор не имеет значения. Поэтому я пытаюсь сделать то же, что и выше, но с перевернутым векторным содержимым, т.е. {3, 2, 1}

std::cout << "count: " << vectorMap.count(std::vector<int>{3, 2, 1}) << std::endl;

. Возвращает счетчик 0.

count: 0

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

{1, 2, 3} count: 1
{3, 2, 1} count: 1
{1, 2} count: 0
{1, 2, 3, 4} count : 0

Как мне этого добиться? Должен ли я использовать другой контейнер вместо std :: vector?

Ответы [ 2 ]

4 голосов
/ 19 апреля 2020

Если порядок элементов в ключе не имеет значения, то вы, вероятно, можете использовать std :: set (если все элементы должны быть уникальными) или std :: multiset, если ключ может иметь повторяющиеся элементы. Т.е. std::map<std::set<int>, std::string>.

1 голос
/ 19 апреля 2020

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

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

struct VectorComparatorOrderless
{
    bool operator()(const std::vector<int>& a, const std::vector<int>& b)const // comparator a < b
    {
        if (a.size() < b.size()) return true;
        if (a.size() > b.size()) return false;

        return !std::all_of(a.cbegin(), a.cend(),
            [&](const int& elementOfVectorA) -> bool
            {
                return std::find(b.cbegin(), b.cend(), elementOfVectorA) != b.cend();
            }
        );
    }
};

typedef std::map<std::vector<int>, std::string, VectorComparatorOrderless> VectorMap;

int main()
{

    VectorMap vectorMap;

    vectorMap[std::vector<int>{1, 2, 3}] = "test";

    std::cout << "count: " << vectorMap.count(std::vector<int>{1, 2, 3}) << std::endl;

    std::cout << "count: " << vectorMap.count(std::vector<int>{3, 2, 1}) << std::endl;

    std::cout << "count: " << vectorMap.count(std::vector<int>{2, 3, 1}) << std::endl;

    std::cout << "count: " << vectorMap.count(std::vector<int>{2, 3}) << std::endl;

    std::cout << "count: " << vectorMap.count(std::vector<int>{2}) << std::endl;

    std::cout << "count: " << vectorMap.count(std::vector<int>{1,2,3,4}) << std::endl;

    std::cin.get();
}

output:

count: 1
count: 1
count: 1
count: 0
count: 0
count: 0
...