简体   繁体   English

在C ++中存储和检索多个密钥

[英]Storing and retrieving multiple keys in 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. 谢谢。

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: 缺少这一点,您可以仅创建一个包含三个int的结构,并定义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;
    }
};

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. 编辑:对于那些关心它的人,使用(std | tr1 | boost):: tuple不会改变答案的性质,但是会消除大部分代码。 A tuple is pretty similar to std::pair , except that it supports an arbitrary number of items instead of just two. 元组非常类似于std::pair ,除了它支持任意数量的项目,而不仅仅是两个。 For the example above, you could use something like: 对于上面的示例,您可以使用类似以下内容的代码:

#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 defines comparison operators automatically assuming the types are comparable (ie, for comparing two tuples with the same number of elements, and the types of corresponding elements are comparable). tuple自动定义比较运算符,假设类型是可比较的(即,用于比较两个具有相同数量元素的元组,并且对应元素的类型是可比较的)。 In this case it does a lexicographic comparison (ie, 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 's suggestion is a nice one, it is extensible to any number of keys of arbitrary width. 杰里·科芬Jerry Coffin )的建议是一个不错的建议,它可以扩展到任意数量的任意宽度的键。

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: 假设我们有三个关键部分:

a, 16-bit,
b, 32-bit
c, 16-bit

listed in the order of significance for comparison. 按重要性顺序列出以进行比较。 (Same as in example of Jerry Coffin .) (与Jerry Coffin的示例相同。)

Then, we can have one value 然后,我们可以有一个价值

class key {
  private:
    uint64_t key_rep_;  // internal key representation
};

with the following underlying interpretation of key_rep_ 对key_rep_的以下基本解释

AAAABBBBBBBBCCCC

Each letter above is a nibble, and shows the key-part it represents. 上面的每个字母都是一个半字节,并显示了它所代表的关键部分。

Comparing this approach with the straightforward one: 将这种方法与简单的方法进行比较:

  • reading and writing key-part into the key are slower 读取和写入密钥部分到密钥较慢
  • comparing two keys are faster 比较两个键更快

In a map or set, comparison of keys are much more frequent than read/write, so this approach, when applicable, achieves overall efficiency. 在映射或集合中,键的比较比读/写要频繁得多,因此,在适用时,此方法可实现整体效率。

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 如果键的数量是常数,您甚至可以以相同的顺序映射int数组

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 . 您可能会遇到的另一种方法是使用从您的三个整数子项生成的哈希码,通过诸如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. 如果std::map为您工作,并且您不需要O(1)查找时间,则移动到基于散列的容器可能会导致散列代码生成的复杂性(不易做好),这比值得的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM