【问题标题】:Boost multi_index: retrieve unique values of a non-unique keyBoost multi_index:检索非唯一键的唯一值
【发布时间】:2011-06-28 08:27:39
【问题描述】:

我有一个boost::multi_index_container,它的元素是这样的结构:

struct Elem {
    A a;
    B b;
    C c;
};

主键(在数据库意义上)是composite_key 中的ab。其他 存在用于执行各种类型查询的键。

我现在需要检索一组所有不同的 c 值。这些值是 无论如何不是唯一的,而是遍历所有条目(尽管是有序的), 或使用std::unique 似乎很浪费,考虑到 c 的不同值的数量预计

我是否缺少一种更有效地获得此结果的简单方法?

【问题讨论】:

  • 你愿意浪费一些额外的内存来加快c值的枚举吗?
  • 您是否使用 C 的 ordered_non_unique 索引以允许 std::unique 遍历已排序的 C 值?

标签: c++ boost boost-multi-index


【解决方案1】:

我浏览了 Boost.MultiIndex 文档,但似乎找不到一种方法来做你想做的事。我有兴趣知道它是否可行。

也许您能做的最好的事情就是在您的multi_index_container 旁边维护一个std::map<C, size_t>(或哈希映射)并保持它们“同步”。

映射将 C 值与其出现次数(频率)相关联。它本质上是 C 值的直方图。每次将Elem 添加到multi_index_container 时,都会增加直方图中的相应频率。当您从 multi_index_counter 中删除 Elem 时,您会减少直方图中的相应频率。当频率达到零时,您从直方图中删除该条目。

要检索一组不同的 C 值,您只需遍历直方图中的 <key,value> 对并查看每对的 key 部分。如果您使用了std::map,那么不同的 C 值将排序出来。

如果您只检查一组不同的 C 值(或很少),那么我上面描述的方法可能是矫枉过正。一种更简单的方法是将所有 C 值插入到 std::set<C> 中,然后遍历该集合以检索不同的 C 值。

你说不同 C 的集合比 C 的总数小得多。因此,std::set<C> 方法应该比将 C 复制到 std::vector、对向量进行排序、然后运行 ​​std::unique 浪费更少的空间。

让我们比较一下复制到集合与复制到向量、排序然后运行unique 的时间复杂度。令 N 为 C 值的总数,令 M 为不同 C 值的数量。根据我的估计,set 方法的时间复杂度应该是 O(N*log(M))。由于 M 很小并且随着 N 的增加不会增长太多,因此复杂度实际上变成了 O(N)。另一方面,排序+唯一技术的时间复杂度应为 O(N*log(N))。

【讨论】:

    【解决方案2】:

    我解决这个问题的方法是使用升压范围适配器,如下所示

    const auto& indexedContainer = container.get<IndexType>();
    const auto uniqueIndexRange = indexedContainer 
        | boost::adaptors::transformed([&](auto&& v) {
            return indexedContainer.key_extractor()(v); })
        | boost::adaptors::uniqued;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-17
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      相关资源
      最近更新 更多