我需要一个(有序的)集合,我可以快速检索成员元素的相对索引

时间:2013-12-20 16:34:46

标签: c++ indexing set

我需要能够做到:

MySet<double> s;
/* some insertions, other ops... */

int idx = s.getElemenetIndex(-15.3);

并且对于idx,如果-15.3不在集合中,则为-1,或者集合中的相对索引为-15.3(即集合中的某个唯一元素的getElemenetIndex()等于0,另一个-1,...到设定大小-1)。我不关心排序是什么,只是它存在。

  • 我可以使用std::set()执行此操作吗?我的意思是,在时间复杂度O(log(n))中,n = s.size()?我知道它的底层实现,一个红黑树,允许这个......
  • 如果不是std::set,也许是其他一些随时可用的套装类?或者我需要自己滚动吗?

备注:

  • 关于动机 - 当我使用这个集合时,我实际上只需要索引。这太复杂了,而且解释我将用它们做什么也不太相关。
  • 我可以“承诺不变”,即您可以假设所有插入都是在第一次调用getElementIndex()之前进行的。
  • 插入(在第一个getElementIndex()之前)必须是O(log(n))摊销;删除不需要任何支持。

2 个答案:

答案 0 :(得分:2)

类似的东西:

std::set<double> s { 5.5, 6.6, 7.7, 8.8 };
auto idx=std::distance(begin(s), s.find(7.7));

查找是对数的,我相信std::distance最坏的情况是O(N)。

编辑:当然我建议你首先检查findend(s)的结果,然后将整个事情包装在一个函数中。

答案 1 :(得分:2)

鉴于在最初填充之后您不需要修改该集,请使用已排序的向量。

  • 使用push_back填充(未排序):按元素分摊O(1)
  • 使用std::sort排序:O(N * log(N))总计,O(log(N))每个元素摊销
  • 使用std::lower_bound找到迭代器:O(log(N))
  • 检查是否相等,并使用std::distance转换为索引:O(1)