如何将向量转换为集合?

93

我有一个向量,其中保存着对象。我需要将它转换成集合(set)。我看了一些关于集合的文章,但还是有几个问题:

  • 如何正确初始化集合?有些教程说可以像这样初始化:set<对象名称> something,而其他人则说你需要在那里使用迭代器,例如:set<迭代器, 对象名称> something

  • 如何正确插入它们?同样,只写something.insert(object)就足够了吗?

  • 如何从集合中获取特定对象(例如,具有命名变量等于“ben”的对象)?

我必须将向量本身转换为集合(也就是说,我必须使用一个集合而不是向量)。


38
set<Type> s(v.begin(), v.end()); 是一种简单的方法。 - Fred Foo
1
@larsmans 不行。我需要完全将向量转换为集合。我不能在我的代码中同时拥有它们两个。 - Marius
@sharth 不行,我只能使用set。我的意思是如何正确地使用set? - Marius
2
所有的答案都涉及使用构造函数,有没有办法在已经构建好的集合上执行此操作? - user712850
https://dev59.com/bmcs5IYBdhLWcg3wcTgz - Ciro Santilli OurBigBook.com
7个回答

202

假设您有一个字符串向量,想要将它转换为集合,可以执行以下操作:

std::vector<std::string> v;

std::set<std::string> s(v.begin(), v.end());

对于其他类型,您必须定义operator<


83
到目前为止,所有的答案都是将一个向量复制到一个集合中。既然您要求“转换”一个向量到一个集合中,我会展示一种更优化的方法,将每个元素移动到一个集合中,而不是复制每个元素。
std::vector<T> v = /*...*/;

std::set<T> s(std::make_move_iterator(v.begin()),
              std::make_move_iterator(v.end()));

请注意,您需要支持C++11。


18

您可以按以下方式使用向量中的对象初始化集合:

vector<T> a;
... some stuff ...
set<T> s(a.begin(), a.end());

这是容易的部分。现在,你必须认识到为了将元素存储在一个集合中,你需要重载bool operator<(const T&a, const T& b)运算符。此外,在集合中,根据运算符定义,对于给定值的元素不能超过一个因此,在集合s中,你不能有两个元素都不满足 operator<(a,b)operator<(b,a)。只要你知道并意识到这一点,你就可以放心使用了。


8

如果你只想将已经在向量中的元素存储到一个集合中:

std::vector<int> vec;
// fill the vector
std::set<int> myset(vec.begin(), vec.end());

5

您并没有告诉我们太多关于您的对象,但假设您有一个类像这样:

class Thing
{
public:
  int n;
  double x;
  string name;
};

你想把一些东西放进一个集合中,所以你尝试了这个方法:

Thing A;
set<Thing> S;
S.insert(A);

这种方式失败了,因为set是有序的,并且没有任何办法可以对Things进行排序,因为没有办法比较两个Things。您必须提供一个operator<

class Thing
{
public:
  int n;
  double x;
  string name;

  bool operator<(const Thing &Other) const;
};

bool Thing::operator<(const Thing &Other) const
{
  return(Other.n<n);
}

...
set<Thing> S;

或者一个比较函数对象:
class Thing
{
public:
  int n;
  double x;
  string name;
};

struct ltThing
{
  bool operator()(const Thing &T1, const Thing &T2) const
  {
    return(T1.x < T2.x);
  }
};

...
set<Thing, ltThing> S;

要查找名称为“ben”的Thing,您可以遍历集合,但如果您更具体地告诉我们您想要做什么,那将非常有帮助。

2
如何正确初始化它?
std::set<YourType> set;

唯一的条件是 YourType 必须有 bool operator<(const YourType&) const 并且可以被复制 (默认构造函数和赋值运算符)。对于 std::vector,可复制就足够了。

如何正确地插入它们。

set.insert(my_elem);

如何从集合中获取特定对象(例如,具有名称变量且其值等于“ben”的对象)?
这可能是关键。集合只是一堆对象,如果您可以检查一个对象是否在其中或遍历整个集合。

好的,假设我们只想找到一个特定名称的对象。怎么做呢? - Marius
你需要遍历整个集合,类似这样:std::find_if(set.begin(), set.end(), [](const YourType& type) { return type.name == "value" }); - Johan
在这种情况下,如果这是唯一(或几乎唯一)搜索元素的方法,那么 std::map<std::string, YourType> 应该更加高效。 - Johan

0

创建一个集合就像创建一个向量一样。你需要

std::vector<int> my_vec;

(或者其他类型而不是int),用它替换掉。

std::set<int> my_set;

要向集合中添加元素,请使用insert

my_set.insert(3);
my_set.insert(2);
my_set.insert(1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接