我正在寻找一个容器,该容器可以很好地根据外部值进行排序。例如,假设我的元素是:pair<char, int>
这对键的键是 not 唯一。举例来说,我有:
'a'
,0
'j'
,13
'm'
,42
'z'
,100
我想通过接近char foo
来保持对该容器的排序,该排序可能会改变,这时我需要对容器进行“动态排序”。举例来说,假设foo
开始于'm'
,我希望这些元素按顺序排列。
'm'
,42
'j'
,13
'a'
,0
'z'
,100
现在将foo
更改为'i'
,我需要在此容器上打个电话以获取顺序:
'j'
,13
'a'
,0
'm'
,42
'z'
,100
我知道我可以使用vector
来做到这一点。那是我最好的选择吗?我确实在寻找一种类似于map
的东西,但是由于排序的不一致,我无法使用它。
答案 0 :(得分:3)
要从排序列表开始对与X相关的内容进行排序,只需找到“ X”在列表中的位置即可。
现在合并(如std::merge
)“ X之后”和“ X之前,向后”两个范围。
提高效率的诀窍是实际上不移动任何东西。将“ sort”应用为延迟或包装操作。
您如何精确执行此操作将取决于您需要执行哪些操作。如果要编写优先级队列,则可以使用std::map
并天真地插入内容。
然后找到最低的元素,使用下/上限,并比较(最多)两个候选者,以找出哪个是“下”。
这会让您的流行度降低到O(lg n)。
如果您需要按此顺序进行迭代,则必须编写一个“合并向前范围”。 “合并正向范围”拥有两个正向迭代器范围和一个比较函数对象;它的迭代器是前向迭代器,并且在每个范围内保留一个迭代器,并且对“最低”(永远不会最低)的结束进行引用和推进,并且==
逐个元素地工作。
就是O(1)在容器上前进。
答案 1 :(得分:2)
为简单起见,假设您要根据到给定整数的距离对整数容器进行排序,然后考虑以下示例(已经按升序排序):
1 2 5 12 20 100
让我们说您要根据到10的距离对它进行排序,那么结果是
12 5 2 1 20 100
现在根据到15的距离进行排序
12 20 5 2 1 100
元素似乎已完全重新排序,但是,如果您考虑分两步进行排序,则很明显不同排序之间的关系。
让我们重新从原始的
开始1 2 5 12 20 100
^------------ 10
^--------- 15
现在,如果您按照到10的距离进行排序,那么您已经完成了一半的工作,因为这两个部分
5 2 1 // first part reversed
12 20 100 // second part
已经排序,您只需要合并它们(简单O(N))。同样根据距离15进行排序:
12 5 2 1 // already sorted
20 100 // already sorted
将它们合并到O(N)中就可以了。
这只是概述想法。我可能会使用简单地按升序排序的std::vector
,然后创建所需的排序就很便宜了。甚至可以想到保持vector
本身总是以递增的顺序进行排序,而只为不同排序的视图提供迭代器。