Я пишу код, в котором храню много объектов, которые я хочу получить, исходя из установленных критериев. Поэтому для меня было целесообразно использовать карту с объектом в качестве ключа. Если объект будет содержать «установленные критерии».Сохранение std :: map сбалансировано при использовании объекта в качестве ключа
Вот упрощенный пример такого рода объектов я имею дело с:
class key
{
int x,y,w,h;
}
class object
{
...
}
std::map<key, object, KeyCompare> m_mapOfObjects;
Довольно просто, первая мысль была создать сравнения функций, как это:
struct KeyCompare
{
bool operator()(const key &a, const key &b)
{
return a.x < b.x || a.y < b.y || a.w < b.w || a.h < b.h;
}
}
, но затем Я думал, что шансы на возвращение верны довольно высокими. Поэтому я решил, что это приведет к очень неуравновешенному дереву и, следовательно, к медленному поиску.
Моя главная забота в том, что, как я понимаю, станд :: карта использует, что одна функция таким образом: если (keyCompare (а, б)) { // левая сторона } еще если (keyCompare (Ь, а)) { // правая сторона } еще { // равно } Таким образом, я не могу просто использовать топор < Ьх, потому что тогда все с тем же х будет считаться равным, что не то, что я хочу. Я бы не возражал, чтобы это упорядочивалось таким образом, но его «равный» бит я просто не могу решить, не делая его неуравновешенным.
Я считаю, что их умножение - это нет, по очевидным причинам.
Таким образом, единственное решение я мог придумать было создать «UID» базу на информации:
typedef long unsigned int UIDType;
class key
{
private:
UIDType combine(const UIDType a, const UIDType b)
{
UIDType times = 1;
while (times <= b)
times *= 10;
return (a*times) + b;
}
void AddToUID(UIDType number)
{
if(number < m_UID)
{
m_UID = combine(number, m_UID);
}
else
{
m_UID = combine(m_UID, number);
}
}
UIDType UID;
public:
int x,y,w,h;
key()
{
AddToUID(x);
AddToUID(y);
AddToUID(w);
AddToUID(h);
}
}
struct KeyCompare
{
bool operator()(const key &a, const key &b)
{
return a.UID < b.UID;
}
}
Но не только, что чувствую себя немного Hacky, «длинный неподписанных Int» не достаточно большой, чтобы удерживать потенциальные числа. I может положить его в строку, но скорость здесь является проблемой, и я предположил, что std :: string < стоит дорого. В целом, хотя меньше я могу сделать этот объект лучше.
Мне было интересно, есть ли у кого-нибудь предложения по тому, как это сделать лучше. Возможно, мне нужно использовать что-то другое, а затем std :: map или, возможно, есть другая перегрузка. Или, может быть, есть что-то очевидное, что я здесь отсутствует. Я действительно чувствую, что я слишком усложняю это, возможно, я действительно лаяю неправильное дерево с картой.
Как я писал это мне пришло в голову, что разрыв еще один способ получить «уникальный» номер, но которые могли бы также равные очень большое количество
один из вопросов, связанных с воспитал термин " лексикографическое упорядочение " Я думаю, что для этого требуется больше исследований! – chrispepper1989
'std :: map', а также' std :: set' уравновешивает себя, иначе они не удовлетворяют критериям сложности из спецификации. –
уверены, что они могут балансировать только на основе функции сравнения? можете ли вы объяснить, как они уравновешивают себя? – chrispepper1989