C++ std::集合中索引处的元素?

C++ std::集合中索引处的元素?,c++,set,std,C++,Set,Std,我偶然发现了这个问题:在正常的std::set中,我似乎无法在索引位置选择项目。这是性病中的一种病菌吗 下面是一个简单的例子: #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(

我偶然发现了这个问题:在正常的
std::set
中,我似乎无法在索引位置选择项目。这是性病中的一种病菌吗

下面是一个简单的例子:

#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!
}
#包括
#包括
int main()
{
设置我的设置;
my_set.insert(0x4A);
my_set.insert(0x4F);
my_set.insert(0x4B);
my_set.insert(0x45);
for(std::set::iterator it=my_set.begin();it!=my_set.end();++it)

std::cout它不会导致崩溃,只是无法编译。
set
没有索引访问权限

可以得到如下所示的第n个元素:

std::set<int>::iterator it = my_set.begin();
std::advance(it, n);
int x = *it;
    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);

同样,您必须知道
n
首先在边界内。

它不会导致崩溃,只是不会编译。
set
没有索引访问权限

可以得到如下所示的第n个元素:

std::set<int>::iterator it = my_set.begin();
std::advance(it, n);
int x = *it;
    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);
同样,您必须知道,
n
首先是有界的

它们不会为您提供对第n个元素的固定时间访问。但是,您似乎想要第一个元素。请尝试:

通常的实现是使用,特别是

它们不会为您提供对第n个元素的固定时间访问。但是,您似乎想要第一个元素。请尝试:


这不是STD中的错误。
STD::set
中没有随机访问。如果需要通过索引进行随机访问,可以使用
STD::vector

这不是STD中的错误。
STD::set
中没有随机访问。如果需要通过索引进行随机访问,可以使用
STD::vector
有时会出现错误我最近不得不实现这个功能,以支持一个遗留API,该API具有返回项目数量和索引中的项目的函数,以便调用方可以枚举项目

我解决这个问题的方法是使用std::vector,并使用std::equal_range查找、插入或删除集合中的项。例如,在集合中插入一个新项如下所示:

std::set<int>::iterator it = my_set.begin();
std::advance(it, n);
int x = *it;
    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);
std:vector my_set;
...
标准::字符串新_项(“测试”);
自动范围=标准::相等范围(my_set.begin()、my_set.end()、new_项);
if(range.first==range.second)
my_set.insert(范围第一,新_项);

删除非常相似:使用equal_range查找项目,如果range.first不等于range.second,则删除该范围。

有时需要一个可以索引到的集合是有充分理由的。我最近不得不实现此功能,以支持一个遗留API,该API具有返回项目数量的函数,并且项目以I为单位ndex,以便调用方可以枚举项

  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];
我解决这个问题的方法是使用std::vector,并使用std::equal_range查找、插入或删除集合中的项。例如,在集合中插入一个新项如下所示:

std::set<int>::iterator it = my_set.begin();
std::advance(it, n);
int x = *it;
    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);
std:vector my_set;
...
标准::字符串新_项(“测试”);
自动范围=标准::相等范围(my_set.begin()、my_set.end()、new_项);
if(range.first==range.second)
my_set.insert(范围第一,新_项);
删除非常类似:使用equal_range查找项目,如果range.first不等于range.second,则删除该范围。

std::set my_set;
  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];
my_set.insert(0x4A); my_set.insert(0x4F); my_set.insert(0x4B); my_set.insert(0x45); int arr[my_set.size()]; set::iterator it=my_set.begin(); 对于(int i=0;istd::设置我的设置; my_set.insert(0x4A); my_set.insert(0x4F); my_set.insert(0x4B); my_set.insert(0x45); int arr[my_set.size()]; set::iterator it=my_set.begin(); 对于(int i=0;icout您无法在固定时间内访问它

但是你可以在O(n)时间内到达任何元素。 例如

std::set::iterator;
它=我的集合。开始();
预付款(it,n);

cout您无法在固定时间内访问它

但是你可以在O(n)时间内到达任何元素。 例如

std::set::iterator;
它=我的集合。开始();
预付款(it,n);

cout我认为
std::set
没有比
O(n)
时间更好的方法,但是我最近使用一个集合和一个二元索引树创建了这个数据结构,它可以做
std::set
可以做的大部分事情,但它也可以获得
O(logn)中元素的索引
time,以及
O((logn)*(logn))中特定索引处的元素。
time:

#包括
#包括

#include.这可能不会在所有编译器中都起作用,但我认为
std::set
没有比
O(n)更好的方法
time,但我最近使用一个集合和一个二元索引树创建了这个数据结构,它可以做
std::set
可以做的大部分事情,但它也可以在
O(logn)
time中获取元素的索引,以及
O((logn)*(logn))
time中特定索引处的元素:

#包括
#包括

#include。这可能不会在所有编译器中都起作用,不过尝试一下,您将能够以另一种方式使用set,即ordered_set

这在CP中非常常用

希望这是所有不同的,将帮助你/某人

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>

试试这个,你将能够以另一种方式使用集合,即有序集合

这在CP中非常常用

希望这是所有不同的,将帮助你/某人

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>

my_set[0]
不应编译。您问的问题是错误的,因为您使用的容器是错误的。每个标准容器在设计时都考虑了一定数量的用途,因此不允许其他容器(直接)。因此,首先,您需要确定您需要的操作,然后确定可能的重复操作最初是一个笑话问题,但答案证明非常有用。如果认真对待,它确实是一个重复操作。
my_set[0]
不应该编译。您