向量循环怪异行为 C++ [复制]

vector loop weird behavior C++ [duplicate]

提问人:Maamar Darmech 提问时间:10/12/2023 更新时间:10/12/2023 访问量:84

问:

我正在从向量中删除重复的整数;我制作的循环按预期工作,但前提是我添加了 Break;在 ' if ' 语句中,否则会给出错误的输出。有人可以解释为什么会这样吗?

#include<iostream>
#include<vector>
using namespace std;

vector<int> nums = {3, 4, 4, 4, 3, 3, 6, 6, 3};

int main() 
{

for(int i = nums.size() - 1 ; i >= 0 ; i--) {
  for( int z = i - 1; z >= 0; z--) {
    if( nums[i] == nums[z] ) {
    nums.erase(nums.begin() + i);
    break; // if i remove it the resault is wrong
    } 
  }
}
for( int c : nums) {
  cout << c << " "; }
} 

如上所述,休息;代码需要,但我不知道为什么。

C++ 循环 向量

评论

1赞 463035818_is_not_an_ai 10/12/2023
什么是调试器,它如何帮助我诊断问题?
0赞 Botje 10/12/2023
假设 i 是向量 (8) 的最后一个元素的索引。每次看到 3 时,您都会分别擦除一个元素(在索引 0、4 和 5 处)并缩小向量。由于不会随着向量而减少,因此您正在越界读取,这意味着突然意味着不同的东西。inums[i]
0赞 463035818_is_not_an_ai 10/12/2023
使用 std::unique 从向量中删除重复项。如果这是练习,您仍然可以使用 ,然后查看可能的实现(相同的链接)。请注意,转折点是要意识到首先重新排列元素,然后才删除要删除的元素更简单(实际上只进行重新排列,同一个链接有一个完整的示例)std::uniquestd::unique
0赞 user12002570 10/12/2023
请参阅如何在循环向量时从向量中删除元素?
0赞 463035818_is_not_an_ai 10/12/2023
您还可以通过调用来替换代码中出现的所有事件,以便对代码中的错误进行更有用的诊断[]at

答:

2赞 Swift - Friday Pie 10/12/2023 #1

erase在擦除元素后使位置(和迭代器)失效并缩小向量。当你“向后”通过向量时,它会产生一个问题,因为你在保持不变时递减,并发现自己超出了界限或引用了相同的元素......这样,您要么擦除整个向量,要么会导致故障(未定义的行为)。zi z

这些是这个问题的意识形态解决方案,不涉及这种复杂的循环。特别是如果向量被排序,这可以通过单个标准库调用或单个循环而不是 N^2 来完成。

评论

0赞 Maamar Darmech 10/13/2023
感谢您提供的信息,但我问为什么要休息;在 if 语句中需要(我的代码工作正常。
0赞 Swift - Friday Pie 10/13/2023
@MaamarDarmech,从我所写的内容来看,这是显而易见的。擦除后退出最内层循环,允许发生递减。如果你不这样做,那么下面的每一个比较都是正确的。(显然你可以在循环中玩法令,但它更奇怪)i