c-std :: unordered_map-如何随时“跟踪”最大/最小键
作者:互联网
我有std :: unordered_map< int,int>.
我不想使用其他结构(例如树)或其他导致延迟要求的结构.
但是在任何时候我都需要知道当前的最大键和最小键.
我怎样才能做到这一点?分布不均匀,而是经常删除和插入max和min.因此,我需要比“仅在删除当前最大/最小时扫描整个地图以获取新的最大/最小”更聪明的方法.
我不想使用任何其他结构.我想使用std :: unordered_map!
upd根据答案创建了这样的结构:
struct OrderBookItem {
int64_t price;
int32_t lots;
};
typedef multi_index_container
<OrderBookItem, indexed_by<
hashed_unique<
BOOST_MULTI_INDEX_MEMBER(OrderBookItem,int64_t,price)
>,
ordered_unique<
BOOST_MULTI_INDEX_MEMBER(OrderBookItem,int64_t,price),
std::greater<int64_t>
>
>> OrderBookContainer;
解决方法:
无法满足您的确切要求:std :: unordered_map快速(即O(1)插入/擦除/查找),因为它不对元素进行排序.这意味着找到最小值/最大值需要O(N).
std :: map支付的订购价格使插入/删除/查找(包括找到最小值/最大值)全部变为O(log N).
如果您不介意使用Boost,可以看一下Boost.MultiIndex库.这使您可以同时通过多个接口访问数据.它是一个用途非常广泛的高性能库,也可以用于MRU缓存数据结构(它还结合了快速访问和对订单的跟踪).
您的主要std :: unordered_map接口由hashed_unique索引提供,您可以在其中使用标识函数对象(由Boost.MultiIndex提供).您的辅助接口将模仿std :: set.这样可以在O(1)时间内找到* begin()和* rbegin()的最小值/最大值.
您可以通过在用户定义的MyOrder函数对象中添加ordered_unique索引来计算您想要用来对它们进行排序的任何条件.小代码示例(在各处省略boost ::名称空间)
using MyContainer = multi_index_container<
Item,
indexed_by<
hashed_unique<identity<Item>>, // O(1) erasure/lookup, O(log N) insertion
ordered_unique<MyOrder<Item>> // track minimum/maximum in O(log N)
>
>;
在后台,Boost.MultiIndex大致将其实现为std :: set< Value>使用std :: unordered_map< Key,设置< Value> :: iterator>.这意味着查找和擦除均为O(1).擦除可以为O(1),因为unordered_map :: erase(value)将迭代器返回到set中,而std :: set< Value> :: erase(iterator)为O(1).
但是,插入仍为O(log N),因为您无法避免在更短的时间内找到有序序列中新插入值的等级.
与用于查找/擦除的std :: map相比,此改进仅花费了每个元素空间开销几个指针.
标签:unordered-map,c,c11,boost,boost-multi-index 来源: https://codeday.me/bug/20191009/1882064.html