什么是实现配对存储的快速数据结构,如此处所指定的?

时间:2014-05-29 12:53:26

标签: c++ algorithm math data-structures hash

我正在尝试实现一对值的存储。它必须公开一个简单的API:newPair, get, remove, isMember。值可以包含4-bit int或指向另一对的指针。所以,例如:

Pointer a = API.newPair(13,12);
Pointer b = API.newPair(a,7);
Pointer c = API.newPair(2,b);
Pointer d = API.newPair(a,7);

等等。但是,只有一个警告:一对不能存储两次。如果您尝试添加已存在的对,它只返回现有指针。因此,例如,在上面的代码中,b == d

我天真的实现涉及一堆对。每次添加一对新对时,我只是迭代堆栈,如果我找到了那对,我就返回它的位置。如果没有,我向堆栈添加了一个新元素并返回了堆栈大小。现在我需要尽可能快地完成它。我目前的想法是只使用哈希表而不是堆栈。

所以,问题是:实现这个的快速方法是什么?

2 个答案:

答案 0 :(得分:3)

双射NxN - >由Cantor Pairing Function

给出的N.

enter image description here

如果N是无限集,则可以使用

。它通过以这种方式连续将NxN的元素分配给N来工作:

enter image description here

当x,y为非负整数时,可以使用ElegantPairing中引入的映射

x >= y ? x * x + x + y : x + y * y;  where x, y >= 0

通过沿着squere的边缘分配值来工作。

代码

int cantor_pairing( int k1, int k2) {
    return 0.5 * ( k1 + k2) * ( k1 + k2 + 1) + k2;
}

int szuzik_pairing( int x, int y) {
    if( x < 0 || y < 0) return -1;
    return x >= y ? x * x + x + y : x + y * y;
}

即使你的整数是统一分布的,你也不能只使用映射

(x,y) - &gt; X

即。完全无视第二个。这是因为在正方形上NxN f(x,y)将是1 / N ^ 2但是边际分布f_y(x)= 1 / N并且这将是碰撞的概率。 毕竟,很可能情况并非如此,因为用户会更频繁地选择小数字然后大。

答案 1 :(得分:1)

如果您的对具有4位元素,则char(在99%的情况下= 8位长)足以存储一对。一点注释:对于一个4位长(带符号)整数,你允许的值范围是:[ - 7,8],但是,在你的例子中,你已经使用了值12和13,所以,我理解你的对由两个4位无符号整数组成。

// a and b should be values between 0 and 15.
// Otherwise, the behaviour is undefined
// (or if you want, you could control the values of
//  a/b and throw an exception in the opposite case).
Pair APIClass::newPair(unsigned a, unsigned b)
{
    char c = (char(a) << 4) | char(b);

    return Pair(c); // `typedef char Pair;` p.e. 
}

假设unsigned s ab介于0到15之间,则为二进制:

a ≡ 0000000000000000000000000000xxxx // 32-bits
b ≡ 0000000000000000000000000000yyyy // 32-bits

目标是:

Pair ≡ xxxxyyyy // 8-bits

因此,发生以下转换:

// For a
0000000000000000000000000000xxxx => conversion to char
0000xxxx                         => 4-bits left-shift
xxxx0000

// For b
0000000000000000000000000000yyyy => conversion to char
0000yyyy

// Result:

      xxxx0000
  |   0000yyyy
--------------
      xxxxyyyy

那就是全部。

最后,如果你的意思是4字节int s,同样的推理适用但使用long long int作为占位符(尽管不是在每个架构中long long int都是64位长)。