Расширенные хэшмапы

Так что я искал вокруг форумов C ++ и не нашел решения. Я пытаюсь создать расширенную хэш-карту со следующими данными:
Возможность хранить значения как реальных, так и строковых.
Возможность хранить ключи как реальные, так и строковые.
Возможность хранить несколько записей (значений) для каждого ключа.

Пример вида результата:

ключ: «ключ» -> значение: 0,5, «45», «66».

ключ: 55 -> значение: «Yo», 27, «67», 88.

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

0

Решение

Если у вас нет аллергии на повышение, вы можете взглянуть на повышение :: вариант. Вы могли бы использовать boost::variant<double, std::string> как ключ и тип значения в хэш-карте, или вы могли бы использовать std::vector<boost::variant<double, std::string>> как тип значения в хэш-карте.

Среди других его достоинств (таких как безопасность типов), boost::variant Тип ishable, если все его типы-члены являются hashable (и оба double а также std::string есть), поэтому вы должны иметь возможность использовать их в качестве ключей в хэш-таблице.

0

Другие решения

Поскольку C ++ является языком со статической типизацией, вы должны либо создать шаблон для любого класса, который вы создаете для этого, либо определить определенный тип для ключа и значения. В качестве альтернативы, вы можете использовать встроенный map<T> тип, который доступен в стандартной библиотеке шаблонов, но опять же — нет способа определить, какой тип нужно использовать для параметра шаблона map<T> во время выполнения.

Вы можете использовать что-то вроде двунаправленной карты. Boost имеет один, и вот код для одного, который я недавно написал:

// bimap.h

#pragma once
#include <string>
#include <list>
using namespace std;

template <typename T0, typename T1>
class bimap
{
public:
bimap(){}

bool Insert(T0, T1);
void Clear();

T0& operator[](T1);
T1& operator[](T0);

private:
list<pair<T0, T1>> m_dictionary;
};

template<typename T0, typename T1>
bool bimap<T0, T1>::Insert(T0 key, T1 value)
{
for (list<pair<T0, T1>>::const_iterator cur = m_dictionary.begin(); cur != m_dictionary.end(); cur++)
{
if ((*cur).first == key)
return false;
}

m_dictionary.push_back(make_pair(key, value));
return true;
}

template<typename T0, typename T1>
void bimap<T0, T1>::Clear()
{
m_dictionary.clear();
}

template<typename T0, typename T1>
T0& bimap<T0, T1>::operator[](T1 key)
{
for (list<pair<T0, T1>>::iterator cur = m_dictionary.begin(); cur != m_dictionary.end(); cur++)
{
if ((*cur).second == key)
return (*cur).first;
}

throw new out_of_range("Key does not exist.");
}

template<typename T0, typename T1>
T1& bimap<T0, T1>::operator[](T0 value)
{
for (list<pair<T0, T1>>::iterator cur = m_dictionary.begin(); cur != m_dictionary.end(); cur++)
{
if ((*cur).first == value)
return (*cur).second;
}

throw new out_of_range("Value does not exist.");
}

Преимущество двунаправленной карты состоит в том, что вы можете получить доступ к ключу, используя значение или значение, используя ключ. Недостатком (по крайней мере, с моим кодом, но я представляю и класс Boost) является то, что он не допускает множественных значений на ключ. Но было бы нетрудно изменить мой код, чтобы позволить это. Вам просто нужно изменить Insert() метод, а затем подумайте, что следует вернуть из operator[] которая берет ключ и возвращает значение, если для данного ключа есть несколько значений. Я не особо задумывался об этом, но мне кажется, что он может вернуть итератор, который можно использовать для перебора значений ключа.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector