将三个32位标识符合并为一个32位标识符?

时间:2014-03-27 14:50:22

标签: algorithm data-structures identity

给定三个标识符,将它们组合成一个32位值。

众所周知,第一标识符可以具有(2 ^ 8)-1个不同的值。类似地,第二(2 ^ 8)-1和第​​三(2 ^ 10)-1。因此,各种标识符的总数不会超过(2 ^ 32)-1。

示例解决方案可能是有一张地图:

  • key:32位,
  • 值:8(或10)位。

该值将从0开始,并在每次提供新标识符时递增。

可以做得更好吗? (而不是3张地图)你觉得这个解决方案有问题吗?


为了阐明,标识符可以保持范围< 0,2 ^ 32)中的任何值。给出的唯一信息是它们的总数不会超过(2 ^ 8)-1(或第10)。

标识符可以具有相同的值(它完全是随机的)。考虑由OS给予堆分配的存储器的随机源存储器地址(例如,使用指针作为标识符)。我意识到这可能在x64系统上有所不同,但是,我希望一般的问题解决方案与这个特定的解决方案类似。

这意味着简单的位移是不可能的。

3 个答案:

答案 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)

你会得到你需要的东西。

相关问题