为何我的vector去重代码会跳过部分元素?
数组去重代码问题排查与验证
初始代码的核心问题
你的初始代码逻辑存在多处硬伤,直接导致元素跳过和数组越界:
- 变量j逻辑完全错误:j是累加状态,每次找到重复就自增,用
vet[i+n+j]赋值会直接访问数组外的内存(越界),因为j持续增大后,访问位置会远超原数组范围。 - 内层循环下标越界:内层循环n从1开始,
i+n很容易超过当前t值(比如i=5、t=10时,n=5会让i+n=10,而数组下标仅到9),触发越界访问。 - 重复元素处理不彻底:找到重复时仅覆盖一次,未将后续所有元素依次前移,导致重复元素残留或出现垃圾值。
- 循环条件冲突:外层循环的
i < t中,t在循环内被修改,会导致遍历提前终止或跳过部分元素。
改写代码的问题(不可行)
改写后的代码同样存在致命缺陷,无法正确运行:
- 内层循环死循环:仅当找到重复时n才自增,否则n一直为1,永远满足
n <= j的条件,程序会卡死。 - 元素移动不完整:仅把
vet[i+n+1]赋值给vet[i+n],未将n位置后续所有元素依次前移,相当于只覆盖单个位置,后续重复元素仍未处理。 - 下标越界:初始j=tam=20,数组下标仅到19,
i <= j会让i=20时访问vet[20],直接触发越界。
正确的手动去重实现思路
要实现类似冒泡的去重逻辑,核心是找到重复元素后将后续所有元素依次前移,同时缩小有效长度,且不跳过未检查元素。以下是可运行的正确代码:
#include <iostream> #define tam 10 using namespace std; int main() { int vet[tam] = {1, 2, 3, 5, 7, 11, 3, 0, 7, 17}; int valid_len = tam; // 记录数组有效元素长度 // 遍历每个有效元素 for (int i = 0; i < valid_len; i++) { int current = vet[i]; // 从当前元素的下一个位置开始检查重复 for (int n = i + 1; n < valid_len; ) { if (current == vet[n]) { // 找到重复,将n后面的所有元素依次前移一位 for (int k = n; k < valid_len - 1; k++) { vet[k] = vet[k + 1]; } valid_len--; // 有效长度减1,丢弃最后一个重复位置 } else { n++; // 无重复时才移动到下一个元素 } } } // 输出去重后的结果 cout << "去重后的数组:" << endl; for (int i = 0; i < valid_len; i++) { cout << vet[i] << " "; } cout << endl; return 0; }
代码逻辑说明:
- 用
valid_len记录当前数组的有效元素数量,初始值为数组总长度。 - 外层循环遍历每个有效元素,内层循环从当前元素的下一个位置开始检查重复。
- 找到重复元素时,通过嵌套循环将该位置后续所有元素依次前移,再将有效长度减1(相当于丢弃最后一个重复位置)。
- 仅当当前元素无重复时,才移动内层循环的下标
n,避免跳过未检查元素。
补充:你提到的是C++的vector,但代码用的是C风格数组。如果使用std::vector,可以直接用标准库的std::unique和erase函数快速去重;若作业要求手动实现,上述逻辑也可移植到vector上(替换数组下标为vector的下标,用vector::size()和vector::pop_back()管理长度)。
内容的提问来源于stack exchange,提问作者Socks
相关产品推荐
相关产品推荐

