我试图将一些元素存储到容器中,并希望根据某些条件有效地获取它。
简单来说,假设:
喜欢以下
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
我能想到几种解决方案:
1。矢量(boost :: circular_buffer?)
e.g. [(23,1,95), (21,2,75), (27,3,85), (21,4,65)]
Insert: O(1)
Delete (can use a bit to mark deleted) O(n)
GetMinSum: O(n)
2。排序矢量
e.g. [(21,2,75), (21,4,65), (23,1,95), (27,3,85)]
Insert: O(n)
Delete (can use a bit to mark deleted) O(n)
GetMinSum: O(1)
3。地图(RB树)
std::map<age, vector<record>>
[(21)->[(2,75),(1,65)], (23)->[(1,95)], (27)->[(3,85)]]
GetMinSum: O(1)
Insert: O(logN)
Delete: O(n)
有什么建议吗?
答案 0 :(得分:1)
应该可以使用O(1)
在std::map
中实施步骤2的计算部分:
std::map<int, int> sum_of_wages_by_age;
地图的关键是Age
。
地图的价值是给定年龄的所有工资的总和。
鉴于迭代std::map
的键必须以严格的弱顺序迭代,最低的Age
将始终是地图中的第一个键。因此,最低年龄的工资总和将只是:
auto p=sum_of_wages_by_age.begin();
return p == sum_of_wages_by_age.end() ? 0: // Edge case, empty map
p->second;
我的回答只关注跟踪此地图的内容,以便以这种方式快速返回最低年龄的工资总和。这与您自己存储<Id, Wage, Age>
记录的方式完全不同。这是一个单独的问题。由您来决定是否要将它们存储在矢量或其他内容中。无论您如何存储它们,sum_of_wages_by_age
的唯一目的是能够快速返回正确的数字。手头的主题只关心能够以这种方式有效地返回最低年龄的工资总和。
为了使这种方法起作用,上述地图需要在插入和删除记录时保持更新。这可以按如下方式完成。
<ID, Age, Wage>
记录。除了存储此记录外,还需要将工资添加到地图中:
sum_of_wages_by_age[age] += wage;
<ID, 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;
请注意,由于之前添加的记录必须已添加,因此您可以保证地图上会显示该年龄的条目。当然,只有wage
不能为零或为负数时,这才有效。但这是一个安全的假设。如你所知,有一项法律规定最低工资必须是什么。
以上示例使用int
s来获取工资。如果您需要使用float
或double
s,则在重复添加和减少期间会出现舍入误差。如果这是一个问题,研究如何正确处理舍入错误将是您的家庭作业。
答案 1 :(得分:1)
确实没有符合您要求的标准容器,但不应该很难编写自己的适配器类。
该类可以包含实际数据的向量,指针的向量或具有当前最小年龄的结构的引用,当前最小年龄本身作为堆栈,以及包含age-&gt; sum映射的映射。 / p>
添加数据:
添加新结构时,比较当前最小年龄(年龄堆栈的顶部),如果它大于当前最小值,则将其添加到数据向量并更新年龄 - >总和映射中的总和
如果年龄等于当前的最低年龄,请添加数据并更新年龄 - >总和地图。
如果新添加的数据的年龄小于当前最小值,请将其添加到数据向量,将新年龄推送到堆栈,并将新条目添加到age-&gt; sum map。
删除数据:
对于所有数据,将其从向量中移除,并更新age-&gt; sum map。
如果年龄等于当前的最小年龄,并且年龄 - >总和映射中的总和已达到零,则弹出年龄堆栈。新总和是年龄 - >总和地图中新年龄的总和。
通过使用您不断更新的地图以及最低年龄的堆栈,您无需重新计算总和,因为它们始终是最新的。