c + set和unordered_set

时间:2018-11-24 01:26:08

标签: c++ set unordered

我正在研究leetcode Frog Jump问题,并在以下测试用例中使用unordered_set而不是set时找到了一些有线结果。 unordered_set和set的大小均为4,但看起来unordered_set并没有遍历所有元素。

[0,1,2,3,4,5,6,7,8,9,10,11] 输出: 设置尺寸4 1
2
3
4
无序集合大小:4 1

挣扎数小时,但找不到任何原因。任何提示都将不胜感激。

bool canCross(vector<int>& stones) {
    unordered_map<int, set<int>> dp;
    unordered_map<int, unordered_set<int>> dp1;
    unordered_set<int> s(stones.begin(), stones.end());
    dp[0].insert(0);
    dp1[0].insert(0);

    for (int i = 0; i < stones.size(); ++i) {
        if (i == 10) cout << "set size " << dp[stones[i]].size() << endl;
        for (auto a: dp[stones[i]]) {
            if (i == 10) cout << a << "\t" << endl;
            int b = stones[i];
            if (s.count(b + a - 1)) {
                dp[b + a - 1].insert(a - 1);   
            }
            if (s.count(b + a)) {
                dp[b + a].insert(a);  
            } 
            if (s.count(b + a + 1)) {
                dp[b + a + 1].insert(a + 1);  
            } 
        }

        if (i == 10) cout << "unordered set size: " << dp1[stones[i]].size() << endl;
        for (auto a: dp1[stones[i]]) {
            if (i == 10) cout << a << "\t" << endl;
            int b = stones[i];
            if (s.count(b + a - 1)) {
                dp1[b + a - 1].insert(a - 1);   
            }
            if (s.count(b + a)) {
                dp1[b + a].insert(a);  
            } 
            if (s.count(b + a + 1)) {
                dp1[b + a + 1].insert(a + 1);  
            } 
        }
    }

    return !dp[stones.back()].empty();
}

1 个答案:

答案 0 :(得分:2)

之所以会发生这种情况,是因为您的某些插入操作会修改您当前在for周期内迭代的同一个容器。毫不奇怪,插入set和插入unordered_set可能会在容器元素的线性顺序中的不同位置结束。在一个容器中,新元素结束于当前位置的 位置,随后在循环中进行迭代。在其他容器中,新元素结束于当前位置 之后,并且在循环中从未出现过。

在基于范围的for循环中修改当前正在迭代的容器通常不是一个好主意。在您的情况下,它可能不会产生任何未定义的行为(如果您使用具有稳定迭代器的关联容器),但是...在我看来,基于范围的for应该保留用于在不变的容器上进行迭代。 / p>

在您的情况下,将新元素插入std::unordered_set可能会触发rehashing并使该unordered_set的所有迭代器无效。这意味着如果当前基于范围的unordered_set正在对for进行迭代,那么您最终将获得不确定的行为。