将整数标识符转换为指针

时间:2009-08-27 05:11:50

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

我有unsigned int类型的ID值。我需要将Id映射到 常量时间 中的指针。


密钥分发:

ID的值范围为0到uint_max。大多数密钥将聚集到一个组中,但会有异常值。


实施

  • 我想过使用C ++ ext hash_map的东西,但我听说当密钥具有巨大的潜在范围时,它们的性能不会太差。

  • 我还想过使用某种形式的链式查找(相当于递归地将范围细分为C chucks)。如果范围中没有键,则该范围将指向NULL。

    N =键范围

    等级0(分为C = 16,所以16件)= [0,N / 16),[N / 16,2 *(N / 16)),...

    1级(分为C = 16,所以16 * 16件)= ...


是否有其他人对如何更有效地实施此映射有想法?

更新

通过常量,我只是意味着每个键查找不会受到项中值的显着影响。我并不是说它必须是单一的操作。

7 个答案:

答案 0 :(得分:11)

使用哈希映射(unordered_map)。这给出了~O(1)查找时间。你“听到”它很糟糕,但你是否尝试过,测试它,并确定它是一个问题?如果没有,请使用哈希映射。

在您的代码接近完成后,对其进行分析并确定查找时间是否是程序缓慢的主要原因。机会是,它不会。

答案 1 :(得分:3)

如果您想要基于树的解决方案并且您的ID在{0..n-1}范围内,那么您可以使用名为van Emde Boas tree的非常酷的数据结构。这将产生O(log log n)中的所有操作并使用O(n)空间。

答案 2 :(得分:1)

你不会得到恒定的时间。

我可能会使用B+Tree

答案 3 :(得分:1)

如果你的整数值是32位宽,那么你可以使用一个64位平台,分配32千兆字节的内存(每40亿个指针8个字节),并使用一个平面数组。这将与你不断寻找持续的查询时间一样接近。

答案 4 :(得分:1)

为此保留4GB的RAM,只需将你的uint转换为指针即可。那绝对是时间。

答案 5 :(得分:1)

正如GMan所说,unordered_map可能是一个很好的解决方案。如果您担心此哈希映射中存在大量冲突,请使用哈希函数来删除数据的群集。例如,您可以交换字节。

值得注意的一点是,您可能会花费更多时间来调试和证明自定义数据结构,而不是已经拥有良好血统的数据结构。

答案 6 :(得分:1)

此类地图中有多少项目以及更改频率?

如果所有值都适合处理器的缓存,那么尽管访问为O(N),但具有预分类值和二分搜索的std::vector<std::pair<unsigned int,T*>>可能是最快的。