插入一个“固定”大小循环设置

问题描述 投票:4回答:5

所以我想插入双所有的元素在我的setset。但很明显我需要抓住结束迭代,这样我就不会继续在迭代的新元素。 (别担心,我查了一下,set::insert不坏迭代:http://www.cplusplus.com/reference/set/set/insert/#validity)所以给出的输入,set<int> foo = { 1, 2, 3 },这里就是我所做的:

for(auto it = begin(foo), finish = end(foo); it != finish; ++it) {
    foo.insert(*it * 2);
}

我希望我的设置包含:

1, 2, 3, 4, 6

惊喜!它包含:

-2147483648, -1073741824, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152, 65536, 98304, 131072, 196608, 262144, 393216, 524288, 786432, 1048576, 1572864, 2097152, 3145728, 4194304, 6291456, 8388608, 12582912, 16777216, 25165824, 33554432, 50331648, 67108864, 100663296, 134217728, 201326592, 268435456, 402653184, 536870912, 805306368, 1073741824, 1610612736

Live Example

显然,因为我认为它没有end(foo)不起作用。所以...如果我要保存环大小和数量来呢?

c++ for-loop insert iterator set
5个回答
2
投票

这显然是圆形的。大小以每一步增加,使得循环永远不会到达终点。

这就像说:就拿这个列表,从第一个元素开始,并继续这样做对所有的要素,当你完成后,多了一个元素添加到同一列表。

为什么会发生这种时候结束?


编辑:

回答:“那么......如果我想保存循环大小和数量来吗?”:

int size = foo.size();
std::set<int> bar;
for(auto it = begin(foo); it != end(foo); ++it) {
    bar.insert(*it * 2);
}
foo.insert(bar.begin(), bar.end());

2
投票

迭代器仍然有效,但作为一个std::set是基于节点的容器中,元素总是排序,所以使用std::less<Key>默认

看看迭代器跳转到较低的值,使之为finish奋斗

Code snippet:

    for(  ; it != finish; ++it)
    {
        auto t = *it  ;
        std::cout << "At " << t  << "\n";
        foo.insert( t * 2  ) ;
        std::cout << "Inserted " << t*2  << "\n";
    }

At 1
Inserted 2
At 2
Inserted 4           <----+
At 3                      |
Inserted 6                | <---+ 
At 4  // jumped back -----+     |
Inserted 8                      |
At 6  // Jumped back -----------+
Inserted 12
At 8
.....

1
投票

这样做的一种典型的方法是通过您的源集进行迭代,并且在每个值来执行你的函数,将所述结果分成第二组。一旦你完成迭代过程,并充分产生的第二组,工会两套在一起。


1
投票

如果你真的想保存循环大小和数量这一点,你可以这样做:

set<int> foo = { 1, 2, 3 };

int setSize = foo.size();
auto it = foo.begin();

for(int i = 0; i < setSize; ++i) {
    foo.insert(*it * 2);
    ++it;
}

copy(cbegin(foo), cend(foo), ostream_iterator<int>(cout, " "));

这会给你的输出:1 2 3 4 6


0
投票

我相信,你的假设是,set被分配到与它最初有足够的空间,连续容器的重新分配是没有必要的假设一个连续的容器;在这种情况下,假定我也希望看到你的行为。 (应该尽管这指出,即使在的情况下这是一个连续的容器,容器的容量将需要验证这种假设,以避免发生不可预料的行为。)

但是,即使在你的问题,你指出insert不坏迭代器,这意味着容器不能是连续的。事实上sets

通常被实现为二叉搜索树

理解这一点你真的只是继续你的循环,直到你的迭代结束指向最后叶节点。你的编译器set实施造成的,当你插入-2147483648元素发生,但这是依赖实现,因此可以表现不同的另一个编译器。

你要找的是定义和编译器的独立行为。取决于你的,你可以扭转在set迭代设定内容的知识:

for(auto it = rbegin(foo); it != rend(foo); ++it) {
    foo.insert(*it * 2);
}

这仅仅是一个很好的解决方案,如果插入创建这些上迭代之后被整理元素。例如,如果foo包含负数这是不行的。你可以通过检查评估此:if(*cbegin(foo) < 0)else块,你可以做反向迭代循环上述建议,但否则你需要做The Quantum Physicist's answer描述一组临时分配。

© www.soinside.com 2019 - 2024. All rights reserved.