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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20477545/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:10:13  来源:igfitidea点击:

Element at index in a std::set?

c++setstd

提问by hauron

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?

我偶然发现了这个问题:我似乎无法在正常的std::set. 这是 STD 中的错误吗?

Below a simple example:

下面是一个简单的例子:

#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!
}

Anything I can do to fix the issue?

我能做些什么来解决这个问题?

回答by Steve Jessop

It doesn't cause a crash, it just doesn't compile. setdoesn't have access by index.

它不会导致崩溃,只是无法编译。set不能按索引访问。

You can get the nth element like this:

您可以像这样获取第 n 个元素:

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:

假设my_set.size() > n,当然。您应该知道,此操作所需的时间大约与 成正比n。在 C++11 中有一种更好的编写方式:

int x = *std::next(my_set.begin(), n);

Again, you have to know that nis in bounds first.

同样,您必须首先知道这n是在界限内。

回答by Basile Starynkevitch

A usual implementation of std::setis to use binary search trees, notably self-balancing binary search treessuch as red-black trees

std::set 的通常实现是使用二叉搜索树,特别是自平衡二叉搜索树,例如红黑树

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:

它们不会让您持续时间访问第 n 个元素。但是,您似乎想要第一个。所以在C++11 中尝试:

auto it = my_set.begin();
int first=0;
if (it != my_set.end()) first = *it;

回答by José D.

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

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

回答by Graham Asher

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.

有时有一个很好的理由需要一个可以索引的集合。我最近不得不实现这个功能来支持一个遗留 API,它具有返回项目数量和索引处的项目的函数,以便调用者可以枚举项目。

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::equal_range在集合中查找和插入或删除项目。例如,向集合中插入一个新项目如下所示:

    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 notequal to range.second, delete that range.

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

回答by Abhishek

There is no way you can access it in constant time.

您无法在恒定时间内访问它。

But you can reach to any element in O(n) time. E.g.

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

std::set<int>::iterator it;
it=my_set.begin();
advance(it,n);
cout<<*it;

回答by katta

  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.

编辑:编辑代码。您不能使用索引访问集合,但如果您想将集合中的元素复制到数组中,上述方法将提供一个“索引” i ,前提是您事先创建了一个足够大小的数组。