用于比较不可代表数字的std :: map技巧?

时间:2012-10-04 10:12:26

标签: c++ math hash stl map

我想在C ++ std::map中有一个用户定义的密钥。键是具有最大值2^V的整数集的二进制表示,因此我无法表示所有2^V个可能的值。我是通过有效的二进制集表示来实现的,即uint64_t

的数组

现在的问题是,要将这个用户定义的bitset作为std::map中的键,我需要定义bitset值之间的有效比较,但如果我的最大大小为,{{1}那么我无法得到一个我可以比较的数字,更不用说将它们全部聚合起来了,即V=1000是不可表示的。

因此我的问题是,假设我有两个不同的集合(通过在我的bitset表示中设置正确的位)并且我不能代表最终的数字,因为它会溢出:

2^1000

是否有合适的转换可以产生我可以比较的价值?我需要能够说id_1 = 2^0 + 2^1 + ... + 2^V id_2 = 2^0 + 2^1 + ... + 2^V 所以我想将指数之和转换为可表示的值,但保持“小于”的不变量。我正在考虑例如以巧妙的方式应用日志转换以保留“小于”。

以下是一个例子:

id_1 < id_2

完美!一般集可以有set_1 = {2,3,4}; set_2 = {8} id(set_1) = 2^2 + 2^3 + 2^4 = 28; id(set_2) = 2^8 = 256 id(set_1) < id(set_2) ,因此{1,...,V}可能的子集怎么样?

1 个答案:

答案 0 :(得分:4)

  

我是通过有效的二进制集表示,即uint64_t数组来实现的。

假设通过密钥类型ra的数据成员Key访问此数组,并且两个数组的长度均为N,那么您需要一个比较器,如下所示:< / p>

bool operator<(const Key &lhs, const Key &rhs) {
    return std::lexicographical_compare(lhs.ra, &lhs.ra[N], rhs.ra, &rhs.ra[N]);
}

这隐含地认为数组是大端的,即第一个uint64_t是最重要的。如果您不喜欢这样,这是公平的,因为您可能已经记住了将V位存储到数组中的任何顺序的相对重要性。 lexicographical_compare没有什么大不了的,所以只需查看an example implementation并根据需要进行修改。

这被称为“词典顺序”。除了我使用uint64_t而不是char并且两个数组长度相同的事实之外,它是比较字符串的方式[*] - 事实上使用uint64_t并不重要,您可以在比较器中使用std::memcmp而不是比较64位块。通过将整个字符串转换为整数,字符串的operator<不起作用,比较器也不应该。

[*]直到您将特定于语言环境的整理规则付诸实践。