遍历集合进入无限循环

时间:2019-03-30 09:11:28

标签: c++11 for-loop iterator each

我在两个文件中使用了完全相同的代码。 一个工作正常,而另一个(这个)进入无限循环。

int arr[5] = {3, 1, 3, 5, 6};
int main() {
    int T = 1; 
    set<int> s;
    for (int tc = 0; tc < T; tc++) {
        s.emplace(0);
        for (auto x : arr) {
            auto end = s.end();
            for (auto it = s.begin(); it != end; it++) {
                // here's where goes to infinite loop
                // and i couldn't figure out why..
                s.emplace(*it+x); 
            }
        }
    }
    return 0;
}

下面一个很好的工作

using namespace std;

int main() {
    int arr[5] = {3,1,3,5,6}, sum=20;
    set<int> s;
    s.emplace(sum);
    for (auto x : arr) {
        auto end = s.end();
        for (auto it = s.begin(); it != end; it++) {
            s.emplace(*it-x);
        }
    }
    return 0;
}

预期结果为s = {1,4,7,8,...} 所有arr子集的总和。 但不能正常工作..我不知道为什么..

1 个答案:

答案 0 :(得分:0)

问题是您要在集合中进行迭代时插入元素(使用range-for循环)。 range-for循环的语义不涉及在循环开始之前记住范围的状态。就像写:

for(auto it = std::begin(container); it < std::end(container); it++)

现在,std::set是一个有序容器。因此,当您插入/放置比迭代器所指向的元素更小的元素 时,您将在以后的迭代中看不到它们。但是如果您插入 large 元素,您将看到它们。因此,最终只能无限地遍历插入的元素。

您可能应该做的是在迭代过程中将新元素放入s中,而是将它们放置在其他容器中,然后最终转储所有这些新容器的内容进入集合(例如,对集合使用std::inserterstd::copy)。

(而且,通常来说,您的所有代码似乎都值得怀疑,也就是说,我怀疑您真的想首先做这些事情。)