在事件驱动的模拟器中,我需要跟踪目录中大量内容元素的流行度。更具体地说,我感兴趣的是知道任何给定内容的等级,即它在列表中按降序请求数排序的位置。我知道每个内容的请求数量每次只会增加一个,因此排名没有显着变化。此外,仅在极少数情况下才会从目录中插入或删除元素,而请求则更多且频繁。实现此目的的最佳数据结构是什么?
这些是我考虑过的选项:
std::map<ContentElement, unsigned int>
将内容映射到他们收到的请求数。这不是一个好的选择,因为它需要我将所有内容转储到列表中,并在我想知道内容的排名时对其进行排序,这很常见。boost::multi_index_container
,一个用于ContentElement的hashed_unique和一个用于请求数量的ordered_not_unique。这允许我快速检索内容以更新其请求数量并通过modify
调用保持容器排序,但我对有序索引的理解是它仍然迫使我迭代通过它的所有元素来计算内容的等级 - 我无法想象从排序的迭代器中提取排名中的位置的简单方法。boost::bimap
,由存储每个内容的请求数的外部排序向量支持。本质上,内容的等级也将表示具有其请求数量的向量元素的索引。这允许我做我想做的所有事情(例如,容易从内容到排名和反之),并且在新请求在bimap中最多需要两次交换之后对矢量进行排序。然而,它感觉笨拙和容易出错,因为我可以很容易地松开地图和矢量之间的同步,然后一切都会崩溃。 我的胆量告诉我必须有一个更简单,更优雅的方式处理这个,但我找不到它。有人可以帮忙吗?
答案 0 :(得分:1)
无需进行全面排序。这里的关键见解是,排名只能在访问时改变+1或-1。我会做以下......
将元素保存在您选择的容器中,例如
map< elementId, elementInstance >
维护元素排名的链接列表,如下所示:
list< rankingInstance >
rankingInstance有一个指向elementInstance的指针以及当前等级和当前访问次数的值。在访问时,您:
答案 1 :(得分:0)
看起来很简单,但我的建议是在列表中使用Bubble Sort
。由于Bubble Sort
只比较和切换相邻元素(在您的情况下),因此只需在排名中向上或向下移动一个元素。您的向量可以将'Rank'作为键,'ContentHash'作为向量中的值。还需要包含'内容'或'内容参考'的地图。我希望这个非常简单的方法可以帮助您解决问题。