给定三个标识符,将它们组合成一个32位值。
众所周知,第一标识符可以具有(2 ^ 8)-1个不同的值。类似地,第二(2 ^ 8)-1和第三(2 ^ 10)-1。因此,各种标识符的总数不会超过(2 ^ 32)-1。
示例解决方案可能是有一张地图:
该值将从0开始,并在每次提供新标识符时递增。
可以做得更好吗? (而不是3张地图)你觉得这个解决方案有问题吗?
为了阐明,标识符可以保持范围< 0,2 ^ 32)中的任何值。给出的唯一信息是它们的总数不会超过(2 ^ 8)-1(或第10)。
标识符可以具有相同的值(它完全是随机的)。考虑由OS给予堆分配的存储器的随机源存储器地址(例如,使用指针作为标识符)。我意识到这可能在x64系统上有所不同,但是,我希望一般的问题解决方案与这个特定的解决方案类似。
这意味着简单的位移是不可能的。
答案 0 :(得分:1)
你可以通过位移和不安全的代码来解决这个问题。
有一篇关于SO的文章:What are bitwise shift (bit-shift) operators and how do they work?
然后您可以将整个32位范围用于三个值
---- 8位---- | ---- 8位---- | ---- 10位---- | ----未使用6位----
int result = firstValue << (8 + 10 + 6);
result += secondValue << (10 + 6);
result += thirdValue << 6;
答案 1 :(得分:1)
您可以尝试这样的事情: -
#include <map>
#include <iostream>
class CombinedIdentifier
{
public:
CombinedIdentifier (unsigned id1, unsigned id2, unsigned id3)
{
m_id [0] = id1;
m_id [1] = id2;
m_id [2] = id3;
}
// version to throw exception on ID not found
static CombinedIdentifier GetIdentifier (unsigned int id)
{
// search m_store for a value = id
// if found, get key and return it
// else....throw an exception->id not found
}
// version to return found/not found instead of throwing an exception
static bool GetIdentifier (unsigned int id, CombinedIdentifier &out)
{
// search m_store for a value = id
// if found, get key and save it to 'out' and return true
// else....return false
}
int operator [] (int index) { return m_id [index]; }
bool operator < (const CombinedIdentifier &rhs) const
{
return m_id [0] < rhs.m_id [0] ? true :
m_id [1] < rhs.m_id [1] ? true :
m_id [2] < rhs.m_id [2];
}
bool operator == (const CombinedIdentifier &rhs) const
{
return m_id [0] == rhs.m_id [0] &&
m_id [1] == rhs.m_id [1] &&
m_id [2] == rhs.m_id [2];
}
bool operator != (const CombinedIdentifier &rhs) const
{
return !operator == (rhs);
}
int GetID ()
{
int
id;
std::map <CombinedIdentifier, int>::iterator
item = m_store.find (*this);
if (item == m_store.end ())
{
id = m_store.size () + 1;
m_store [*this] = id;
}
else
{
id = item->second;
}
return id;
}
private:
int
m_id [3];
static std::map <CombinedIdentifier, int>
m_store;
};
std::map <CombinedIdentifier, int>
CombinedIdentifier::m_store;
int main ()
{
CombinedIdentifier
id1 (2, 4, 10),
id2 (9, 14, 1230),
id3 (4, 1, 14560),
id4 (9, 14, 1230);
std::cout << "id1 = " << id1.GetID () << std::endl;
std::cout << "id2 = " << id2.GetID () << std::endl;
std::cout << "id3 = " << id3.GetID () << std::endl;
std::cout << "id4 = " << id4.GetID () << std::endl;
}
答案 2 :(得分:1)
我认为你可以使用a Perfect Hash Function。特别是,那篇文章提供给Pearson Hashing的链接似乎是合适的。您甚至可以在第二篇文章中剪切并粘贴包含的C程序,除了它的输出是64位数而不是32位数。但是如果你从
稍微修改它for (j=0; j<8; j++) {
// standard Pearson hash (output is h)
到
for (j=0; j<4; j++) {
// standard Pearson hash (output is h)
你会得到你需要的东西。