8

我想创建一组数字范围:0, 1, 2, 3, 4, ... 以下代码无法编译:

std::set<int> s;
std::iota(s.begin(), s.end(), 0);

带有以下错误消息:

error C3892: '_First' : you cannot assign to a variable that is const

编译器是VC++2012。相同的代码适用于向量。我应该如何将它与一组一起使用?

更新

我现在可以看到我的代码毫无意义,因为没有指定设置大小。

以下是有关我的问题的更多详细信息。

我有一组包含 [0, N] 范围内的一些数字。在我的应用程序中,我需要多次计算此类集合的集合差异。N 是固定的。

假设N = 5第一组是s1 = {0, 3, 4}。我需要计算设置差异{0, 1, 2, 3, 4} \ {0, 3, 4} == {1, 2}。这个操作应该经常针对不同的集合执行,所以我认为我可以创建一个包含所有数字的集合({0, 1, 2, 3, 4}在这种情况下)并std::set_difference用来计算这些差异。

4

3 回答 3

14

解决您的实际问题:与您预期std::set_difference的关系不大。std::set您可以使用任何一对迭代器作为前两个参数,set_difference前提是它们按顺序返回值。作为一个集合并没有什么特别的好处。

因此,例如,std::vector包含值 0 ... n-1 的 a 的开始/结束迭代器将起作用,或者一对boost::counting_iterator

std::set result;
std::set_difference(
    boost::counting_iterator<int>(0), boost::counting_iterator<int>(n),
    s1.begin(), s1.end(),
    std::inserter(result, result.end())
);

输出也不需要是一个集合,你也可以使用 a vectorwith back_inserter

解决您的问题:尝试在集合上使用是没有意义iota的。iota通过为它们分配新值来更改范围中包含的值。您不能分配给 a 中的值set

如果你想要一个包含 numbers 的集合0 ... n-1,那么:

std::set<int> s;
for (int i = 0; i < n; ++i) {
    s.insert(s.end(), i);
}

iota如果有人告诉你循环是为 wusses 设计的,而真正的 C++ 程序员使用算法,那么如果你真的想要的话,你可以参与进来:

std::set<int> s;
{
    std::vector<int> vec(n);
    std::iota(vec.begin(), vec.end(), 0);
    s.insert(vec.begin(), vec.end());
}

不幸的是,这有点低效。因此,如果您如此热爱算法以至于您不妨将它们嫁给它们,那么您可以超越标准库:

std::set<int> s(boost::counting_iterator<int>(0), boost::counting_iterator<int>(n));
于 2013-10-22T22:28:47.313 回答
4

一个稍微不优雅的替代方案:

set<int> s;
generate_n(inserter(s, s.end()), 10, [&]{ return s.size(); });
于 2013-10-22T22:39:55.630 回答
1

集合与向量的不同之处在于向量具有从索引到存储在该索引处的值的关联,而集合仅具有值是否在集合中的信息。所以给集合元素赋值是没有意义的——强制它的方法是集合中的元素是常量。

等效的方法是删除集合中不需要的值(向量中的“旧”值),然后遍历您想要存储的值(使用 itoa一系列增加的值)并将它们一个接一个地添加到集合中。

于 2013-10-22T22:28:15.417 回答