我有一些检索值所需的整数键。基于密钥存储和检索值的最有效方法是什么?
目前,我正在将三个键转换并组合成一个字符串,并将键值对存储在地图中。但是,我认为应该有一种更有效的方法,仅基于整数值,例如基于三个键生成单个键。有什么想法?
感谢。
答案 0 :(得分:9)
你几乎可以肯定比转换为字符串更好(这通常是一个非常慢的操作)。如果你的三个项目的范围足够小,你可以进行一些移动和添加,将它们组合成一个范围更大的整数。
缺乏这一点,你可以创建一个包含三个整数的结构,并定义operator<
以合理的方式比较它们:
class key {
int a, b, c;
public:
bool operator<(key const &other) {
if (a < other.a)
return true;
if (a > other.a)
return false;
if (b < other.b)
return true;
if (b > other.b)
return false;
if (c < other.c)
return true;
return false;
}
};
编辑:对于那些关心它的人来说,使用(std | tr1 | boost):: tuple不会改变回答的字符,但会消除大部分代码。元组与std::pair
非常相似,只不过它支持任意数量的项而不是两个。对于上面的示例,您可以使用类似:
#include <tuple>
namespace stdx = std::tr1; // or stdx=boost::tr1, etc.
typedef stdx::tuple<int, int, int> key_t;
std::map<key_t, whatever> my_map;
tuple
自动定义比较运算符,假设类型具有可比性(即,用于比较具有相同元素数的两个元组,并且相应元素的类型是可比较的)。在这种情况下,它进行字典比较(即,比较的结果是第一对不相等的相应元素的结果 - 不存在这样的元素,两者相等)。
答案 1 :(得分:2)
Jerry Coffin的建议很好,它可以扩展到任意数量的任意宽度的键。
然而,在实践中,存在许多可以采用以下有效方法的情况。如果键的大小使得它们的总和适合本机类型,那么我们可以将键组成如下。
假设我们有三个关键部分:
a, 16-bit,
b, 32-bit
c, 16-bit
按重要性顺序列出进行比较。 (与Jerry Coffin的例子相同。)
然后,我们可以有一个值
class key {
private:
uint64_t key_rep_; // internal key representation
};
具有key_rep _
的以下基本解释AAAABBBBBBBBCCCC
上面的每个字母都是一个半字节,并显示它代表的关键部分。
将这种方法与直截了当的方法进行比较:
在地图或集合中,密钥的比较比读/写更频繁,因此这种方法(如果适用)可以实现整体效率。
答案 2 :(得分:0)
您可以使用地图将带有键的向量映射到值,并使用字典顺序排列地图。如果键的数量是常数,您甚至可以使用相同的顺序映射int数组
答案 3 :(得分:0)
你在做什么听起来不错。您可能会想到的另一种方法是使用从三个整数子项生成的哈希码来通过unordered_map之类的方式访问值。
如果std::map
对您有用并且您不需要O(1)查找时间,那么迁移到基于散列的容器可能会引入哈希码生成的复杂性(不容易做得好)它比它的价值更麻烦。