快速获取多个最小(最大)元素C++的数据结构

快速获取多个最小(最大)元素C++的数据结构,c++,boost,stl,C++,Boost,Stl,我正在尝试将一些元素存储到容器中,并希望根据一些标准高效地获取它 简单来说,假设: 记录如下:身份证、年龄、工资 对于每个插入和删除,它返回最低年龄的工资总额 像下面 ID Age Wage(k) insert 1 23 95 // returns 23,95 insert 2 21 75 // returns 21,75 insert 3 27 85 // returns 21,75 insert 4 21 65 // returns 2

我正在尝试将一些元素存储到容器中,并希望根据一些标准高效地获取它

简单来说,假设:

记录如下:身份证、年龄、工资 对于每个插入和删除,它返回最低年龄的工资总额 像下面

       ID  Age Wage(k)
insert 1   23  95   // returns 23,95
insert 2   21  75   // returns 21,75
insert 3   27  85   // returns 21,75
insert 4   21  65   // returns 21,140
delete ID=2         // returns 21,65
我可以想到几种解决方案:

一,。向量提升::循环缓冲区

二,。排序向量

三,。映射RB树


有什么建议吗?

应该可以使用std::map实现O1中步骤2的计算部分:

我的回答只涉及跟踪这张地图的内容,这样最低年龄的工资总额就可以通过这种方式快速返回。这与存储记录的方式完全不同。那是另一个问题。由您自己决定是否要将它们存储在向量中或其他形式。无论您如何存储它们,按年龄计算工资总额的唯一目的是能够快速返回正确的数字。目前的主题只是能够以这种方式有效地返还最低年龄的工资总额

为了使这种方法发挥作用,每当插入和删除记录时,都需要更新上面的映射。这可以按如下方式进行

添加新记录。 除了存储此记录外,只需将工资添加到地图:

sum_of_wages_by_age[age] += wage;
删除现有记录 这一个更令人兴奋一点

auto p=sum_of_wages_by_age.find(age);

if ( (p->second -= wage) == 0)
    sum_of_wages_by_age.erase(p);
你想保持整洁。删除给定年龄的最后一条记录后,您现在希望从此地图中完全删除该年龄的条目。如果你不在乎这一点,你可以简单地去做

sum_of_wages_by_age[age] -= wage;
请注意,由于要删除的记录必须是先前添加的记录,因此可以保证地图将有一个年龄条目。当然,这只有在工资不能为零或负的情况下才会起作用。但这是一个安全的假设。如你所知,有一项法律规定最低工资必须是多少

警告
以上示例使用整数表示工资。如果需要使用浮点或双精度,则舍入误差将在重复的加减过程中累积。如果这是一个问题,研究如何正确处理舍入错误将是你的家庭作业。

确实没有满足你要求的标准容器,但编写自己的适配器类应该不会太难

该类可以包含实际数据的向量、指向具有当前最小年龄的结构的指针或引用的向量、当前最小年龄本身作为堆栈以及包含年龄->和映射的映射

添加数据:

添加新结构时,比较年龄堆栈顶部的当前最小年龄,如果它大于当前最小年龄,则只需将其添加到数据向量,并在年龄->总和映射中更新总和

如果年龄等于当前最小年龄,则添加数据并更新年龄->总和映射

如果新添加数据的年龄小于当前最小值,则将其添加到数据向量中,将新年龄推送到堆栈上,然后向年龄->总和映射添加新条目

删除数据:

对于所有数据,将其从向量中删除,并更新年龄->总和映射

如果年龄等于当前最小年龄,并且年龄->总和映射中的总和已达到零,则弹出年龄堆栈。新总和是年龄->总和映射中新年龄的总和


通过使用不断更新的地图和一堆最短年龄,您不必重新计算总数,因为它们总是最新的。

有什么建议吗?为了什么?更好的容器?你能澄清一下吗?这个问题没有任何意义,包括你声称的算法运行时。你可以在std容器周围使用一些包装器,并在插入时更新最小值/最大值。@raket1111关于如何解决此问题以获得Insert/Delete/GetMinSumI的最佳性能的建议将使用3 a类的变体,该类具有数据成员std::map,其中结构记录{int ID;int Age;double Wage;};和适当的插入/删除方法,返回所需的信息。对于添加数据,如果年龄大于当前最小值,我想仍然需要将其添加到最小堆栈中,而堆栈这样做并不十分方便so@Deqing嗯,没错。你应该教我不要在早餐前早早回答问题这是真的,如果年龄不在堆栈中,这将是一个问题。我会在白天多想一想,看看能不能想出点办法。无论如何,这和Sam的答案应该是一个很好的起点。@Deqing您实际上不需要堆栈。在密钥上排序,在我的算法中是年龄。最低年龄最小的钥匙将始终是地图中的第一对,最老的最高钥匙将始终是最后一对。因此,只需跳过堆栈并保留映射,它将同时跟踪和和和
最低年龄。看起来是个好办法。除了你的std::map之外,我正在考虑使用id->record的无序_映射来存储记录,这样我们就可以插入和删除O1。你希望如何在无序_映射中轻松找到最小键,在O1中?最小值已经存储在你的std::map中。也就是说,我需要一张地图和一张无序的地图。
std::map<int, int> sum_of_wages_by_age;
auto p=sum_of_wages_by_age.begin();

return p == sum_of_wages_by_age.end() ? 0: // Edge case, empty map
          p->second;
sum_of_wages_by_age[age] += wage;
auto p=sum_of_wages_by_age.find(age);

if ( (p->second -= wage) == 0)
    sum_of_wages_by_age.erase(p);
sum_of_wages_by_age[age] -= wage;