I\'ve stumbled upon this problem: I can\'t seem to select the item at the index\' position in a normal std::set
. Is this a bug in STD?
Below a simple ex
std::set<int> my_set;
my_set.insert(0x4A);
my_set.insert(0x4F);
my_set.insert(0x4B);
my_set.insert(0x45);
int arr[my_set.size()];
set<int>::iterator it = my_set.begin();
for (int i = 0; i < my_set.size(); i++) {
arr[i] = *it;
it++;
}
cout << arr[0];
Edit: Edited code. You can't access set using index but the above method would provide an "index" i if you want to copy the elements from set into an array, provided you have created an array of sufficient size before hand.
There is no way you can access it in constant time.
But you can reach to any element in O(n) time. E.g.
std::set<int>::iterator it;
it=my_set.begin();
advance(it,n);
cout<<*it;
A usual implementation of std::set is to use binary search trees, notably self-balancing binary search trees such as red-black trees
They don't give you constant time access to the n-th element. However, you seems to want the first. So try in C++11:
auto it = my_set.begin();
int first=0;
if (it != my_set.end()) first = *it;
This is not a bug in the STD. There is no random access in a std::set
. If you need random access by index, you can use std::vector
It doesn't cause a crash, it just doesn't compile. set
doesn't have access by index.
You can get the nth element like this:
std::set<int>::iterator it = my_set.begin();
std::advance(it, n);
int x = *it;
Assuming my_set.size() > n
, of course. You should be aware that this operation takes time approximately proportional to n
. In C++11 there's a nicer way of writing it:
int x = *std::next(my_set.begin(), n);
Again, you have to know that n
is in bounds first.
Sometimes there's a good reason for needing a set you can index into. I had to implement this functionality recently to support a legacy API which has functions to return the number of items, and the item at an index, so that the caller can enumerate the items.
My way of solving the problem is to use std::vector, and use std::equal_range to find and insert or delete items in the set. For example, inserting a new item into the set looks like this:
std:vector<std::string> my_set;
...
std::string new_item("test");
auto range = std::equal_range(my_set.begin(),my_set.end(),new_item);
if (range.first == range.second)
my_set.insert(range.first,new_item);
Deleting is very similar: use equal_range to find the item, and if range.first is not equal to range.second, delete that range.