Element at index in a std::set?
我偶然发现了这个问题:我似乎无法在普通
下面是一个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <iostream> #include <set> int main() { std::set<int> my_set; my_set.insert(0x4A); my_set.insert(0x4F); my_set.insert(0x4B); my_set.insert(0x45); for (std::set<int>::iterator it=my_set.begin(); it!=my_set.end(); ++it) std::cout << ' ' << char(*it); // ups the ordering //int x = my_set[0]; // this causes a crash! } |
我可以采取什么措施解决此问题?
它不会导致崩溃,只是不会编译。
您可以这样获得第n个元素:
1 2 3 | std::set<int>::iterator it = my_set.begin(); std::advance(it, n); int x = *it; |
当然,假设
1 | int x = *std::next(my_set.begin(), n); |
同样,您必须知道
std :: set的通常实现是使用二进制搜索树,尤其是自平衡二进制搜索树,例如红黑树。
它们不能让您恒定时间访问第n个元素。但是,您似乎想要第一个。因此,请尝试在C ++ 11中:
1 2 3 | auto it = my_set.begin(); int first=0; if (it != my_set.end()) first = *it; |
您无法在恒定时间内访问它。
但是您可以在O(n)时间内到达任何元素。
例如。
1 2 3 4 | std::set<int>::iterator it; it=my_set.begin(); advance(it,n); cout<<*it; |
有时,有充分的理由需要您可以索引的集合。最近,我必须实现此功能以支持旧版API,该API具有返回项数和索引项的功能,以便调用者可以枚举项。
解决问题的方法是使用std :: vector,并使用std :: equal_range查找和插入或删除集合中的项目。例如,将新项目插入到集合中看起来像这样:
1 2 3 4 5 6 7 8 9 | 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); |
删除非常相似:使用equal_range查找项目,如果range.first不等于range.second,则删除该范围。
这不是STD中的错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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]; |
编辑:编辑的代码。您无法使用索引访问集合,但是如果您想事先将集合中的元素复制到数组中,则上述方法将提供一个"索引",前提是您已事先创建了足够大的数组。