在 C++ 中存储和检索多个密钥
我有一些检索值所需的整数键。基于键存储和检索值的最有效方法是什么?
目前,我正在将三个键转换并组合成一个字符串,并将键值对存储在映射中。但是,我认为应该有一种更有效的方法来仅基于整数值来执行此操作,例如基于三个键生成单个键。对此有什么想法吗?
谢谢。
I have a few integer keys that is needed to retrieve a value. What is the most efficient way to store and retrieve the value based on the keys?
Currently I am converting and combining the three keys into a single string and store the key-value pair in a map. However, I think there should be a more efficient way of doing that based on the integer value alone for example generating a single key based on the three keys. Any ideas on that?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
几乎可以肯定,您可以比转换为字符串做得更好(这通常是一个相当慢的操作)。如果您的三个项目的范围足够小,您可以进行一些移位和添加,将它们组合成一个具有更大范围的整数。
如果缺少这一点,您可以创建一个包含三个整数的结构,并定义
operator<
以合理的方式比较它们:编辑:对于那些关心它的人,使用 (std | tr1 | boost) ::tuple 不会改变答案的特征太多,但会消除大部分代码。元组与 std::pair 非常相似,不同之处在于它支持任意数量的项目而不是仅两个。对于上面的示例,您可以使用类似的内容:
tuple
自动定义比较运算符,假设类型是可比较的(即,用于比较具有相同元素数量的两个元组,并且相应元素的类型是可比较的)。在这种情况下,它进行字典比较(即,比较的结果是第一对不相等的相应元素的结果——如果不存在这样的元素,则两个比较相等)。You can almost certainly do better than converting to a string (which is generally quite a slow operation). If your three items have small enough ranges, you can do some shifting and adding to put them together into a single integer with a larger range.
Lacking that, you can just create a struct that holds three ints, and defines
operator<
to compare them in a reasonable fashion:Edit: for those who care about it, using (std | tr1 | boost)::tuple wouldn't change the character of answer much, but would eliminate most of the code. A tuple is pretty similar to
std::pair
, except that it supports an arbitrary number of items instead of just two. For the example above, you could use something like:tuple
defines comparison operators automatically assuming the types are comparable (i.e., for comparing two tuples with the same number of elements, and the types of corresponding elements are comparable). In this case it does a lexicographic comparison (i.e., the result of the comparison is the result from the first pair of corresponding elements that are not equal -- of no such element exists, the two compare equal).Jerry Coffin 的建议很好,它可以扩展到任意数量的任意宽度的键。
然而,在实践中,有很多情况可以采用以下有效方法。如果键的大小使其总和适合本机类型,那么我们可以按如下方式组合键。
假设我们有三个关键部分:
按重要性顺序列出以进行比较。 (与 Jerry Coffin 的示例相同。)
然后,我们可以
通过 key_rep_ 的以下底层解释
获得一个值上面的每个字母都是一个半字节,并显示了它所代表的关键部分。
将此方法与直接方法进行比较:
在映射或集合中,键的比较比读/写更频繁,因此此方法在适用时可以实现整体效率。
Jerry Coffin's suggestion is a nice one, it is extensible to any number of keys of arbitrary width.
However, in practice, there are many situations where the following efficient method can be employed. If the size of the keys are such that their sum fits into a native type, then we can compose the key as following.
Suppose we have three key-parts:
listed in the order of significance for comparison. (Same as in example of Jerry Coffin.)
Then, we can have one value
with the following underlying interpretation of key_rep_
Each letter above is a nibble, and shows the key-part it represents.
Comparing this approach with the straightforward one:
In a map or set, comparison of keys are much more frequent than read/write, so this approach, when applicable, achieves overall efficiency.
您可以使用映射将带有键的向量映射到值,并对映射使用字典顺序。如果键的数量是恒定的,您甚至可以使用相同的顺序映射 int 数组
you can map a vector with the keys to the value with a map and use a lexicographical ordering for the map. If the number of keys is constant you can even map arrays of int with the same ordering
你正在做的事情听起来不错。您可能会想到的另一种方法是使用从三个整数子项生成的哈希码来通过类似 unordered_map。
如果 std::map 适合您并且不需要 O(1) 查找时间,那么迁移到基于哈希的容器可能会导致哈希代码生成变得复杂(不容易做好) )这让它带来的麻烦超过了它的价值。
What you are doing sounds fine. An alternative that you may be feeling your way towards would be to use a hash code generated from your three integer subkeys to access the values via something like unordered_map.
If the
std::map
is working for you and you don't need O(1) lookup time, moving to a hash-based container could introduce complexity in hash code generation (not easy to do well) that makes it more trouble than it is worth.