我遇到了以下问题:
假设我有一个名为Numbers的std :: set,包含n个值。我想插入第(n + 1)个值(等于x),我事先知道它不在集合中。我需要的是一些方法来检查,它将插入哪个位置,或者等效地,在NUM中已经包含了少于x的元素。
我绝对知道在O(n)做某些方法,但我需要的是O(log(n))。从理论上讲,std :: set通常可以实现为二进制搜索树(假设O(log(n))只有在每个顶点存储有关每个子树大小的信息时才有可能)。问题是它是否在技术上是可行的,如果是,那该怎么做。
答案 0 :(得分:1)
集合中没有“位置”,迭代器和集合没有给出关于实现的承诺。你可以使用lower / upper_bound和count元素,但我认为不会考虑内部因素。
答案 1 :(得分:1)
所有set
函数都将与迭代器一起使用; set
的迭代器是双向的,而不是随机访问,因此确定位置将是O(n)操作。
您不需要知道在集合中插入新元素的位置,插入是O(log n)。
答案 2 :(得分:0)
你可以使用set::lower_bound
找到将这个新元素插入O(lon(n))的“position”,但它只是一个迭代器。 std :: set :: iterator是双向的,而不是随机访问,所以你不能计算在O(lon(n))中有多少元素小于新的元素
答案 3 :(得分:0)
也许您应该使用set :: lower_bound(),根据此(http://lafstern.org/matt/col1.pdf)文档,该时间应与log N
成比例答案 4 :(得分:0)
而不是:
std::set<MyT> mySet;
使用:
std::set<std::pair<MyT,int>> mySet;
然后,例如:
//inserting a std::vector<MyT> myVec:
for (int i=0; i<myVec.size(); i++)
mySet.insert( std::pair<MyT,int>(myVec[i], i) );
排序结果:
for (auto it=mySet.begin(); it!=mySet.end(); ++it)
cout << it->first << " index=" << it->second << "\n";