2

长期读者第一次海报!我正在玩 boost::multi_index 容器的东西,并且有一个相当深入的问题,希望 boost 或 C++ 容器专家可能知道(我在 C++ 容器方面的知识非常基础)。作为参考,可以在此处找到有关复合键的 boost 文档:boost::multi_index 复合键。

使用复合键时,文档指出“复合键按字典顺序排序,即按第一个键执行排序,如果第一个键相等,则按第二个键执行排序,等等”。这是否意味着存储该结构,以便查找特定的 2 部分复合键将花费 O(n=1) 时间,即容器是否已排序,以便有一个直接指向每个项目的指针,或者提升容器检索与组合键的第一部分匹配的列表,然后需要搜索与键的第二部分匹配的项目,因此速度较慢?

例如,如果我要使用两个不同的索引手动维护两个容器,并且想要查找与特定 2 部分查询匹配的项目,我可能会过滤第一个容器以查找与查询的第一部分匹配的所有项目,然后过滤与查询的第二部分匹配的项目的结果。因此,这种手动方法将有效地涉及两次搜索。boost 是否有效地做到了这一点,或者它是否通过使用复合键以某种方式提高了效率?

希望我已经在这里解释了自己,但请提出问题,我会尽力澄清我的意思!

4

1 回答 1

4

如您所描述的,涉及复合键的查找不会经历任何两阶段过程。composite_key-诱导排序是正常的排序,唯一的特殊之处在于它依赖于两个或多个元素键而不是一个。

也许一个例子会澄清。考虑这种用法composite_key

struct element
{
  int x,y,z;
};

typedef multi_index_container<
  element,
  indexed_by<
    ordered_unique<
      composite_key<
        element,
        member<element,int,&element::x>,
        member<element,int,&element::y>,
        member<element,int,&element::z>
      >
    >
  >
> multi_t;

生成的容器在某种意义上等同于:

struct element_cmp
{
  bool operator()(const element& v1, const element& v2)const
  {
    if(v1.x<v2.x)return true;
    if(v2.x<v1.x)return false;
    if(v1.y<v2.y)return true;
    if(v2.y<v1.y)return false;
    return v1.z<v2.z;
  }
};

typedef std::set<element,element_cmp> set_t;

composite_key自动生成与 in 等效的代码element_cmp::operator(),并且还允许仅查找前 n 个键,但底层数据结构不会相对于使用std::set.

于 2013-12-01T19:49:30.647 回答