我正在编写一些代码,其中存储了许多我想根据设定标准取回的对象。所以对我来说,使用带有对象作为键的地图是有意义的。对象将包含“设置标准”的位置。
这是我正在处理的对象类型的简化示例:
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;
}
}
但后来我认为这回归真实的机会非常高。所以我认为这会导致树非常不平衡,因此搜索速度很慢。
我主要担心的是,据我了解,std::map 以这种方式使用该函数: if(keyCompare(a,b)) { //left side } else if (keyCompare(b,a)) { // right side } else { //equal } 所以我不能只使用 ax < bx,因为这样任何具有相同 x 的东西都会被认为是相等的,这不是我想要的。我不介意以这种方式订购它,但它的“相等”位我似乎无法在不使其不平衡的情况下解决。
我认为将它们全部相乘是不可以的,原因很明显。
所以我能想出的唯一解决方案是根据信息创建一个“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,“long unsigned int”还不足以容纳潜在的数字。我可以把它放在一个字符串中,但是速度在这里是一个问题,我认为 std::string < 很昂贵。总的来说,虽然我越小可以使这个对象越好。
我想知道是否有人对如何更好地做到这一点有任何建议。也许我需要使用 std::map 以外的东西,或者可能还有另一个重载。或者也许我在这里遗漏了一些明显的东西。我真的觉得我过于复杂了,也许我真的用地图在错误的树上吠叫。
当我写这篇文章时,我突然想到除法是获得“唯一”数字的另一种方式,但也可能等于非常大的数字