我正在研究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();
}
答案 0 :(得分:2)
之所以会发生这种情况,是因为您的某些插入操作会修改您当前在for
周期内迭代的同一个容器。毫不奇怪,插入set
和插入unordered_set
可能会在容器元素的线性顺序中的不同位置结束。在一个容器中,新元素结束于当前位置的 位置,随后在循环中进行迭代。在其他容器中,新元素结束于当前位置 之后,并且在循环中从未出现过。
在基于范围的for
循环中修改当前正在迭代的容器通常不是一个好主意。在您的情况下,它可能不会产生任何未定义的行为(如果您使用具有稳定迭代器的关联容器),但是...在我看来,基于范围的for
应该保留用于在不变的容器上进行迭代。 / p>
在您的情况下,将新元素插入std::unordered_set
可能会触发rehashing并使该unordered_set
的所有迭代器无效。这意味着如果当前基于范围的unordered_set
正在对for
进行迭代,那么您最终将获得不确定的行为。