You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ vector调用insert插入元素结果不符合预期的原因解析

问题说明

需求:为std::vector中的每个原有元素,在其紧邻后方插入对应的相反数,要求不允许使用辅助vector或其他额外数据结构。

错误实现代码:

#include <iostream>
#include <vector>
int main() {
  std::vector < int > vek {1,2,3};
  std::cout << vek[0] << " " << vek[1] << " " << vek[2] << std::endl;
  for (int i = 0; i < 3; i++) {
    std::cout << i << " " << vek[i] << std::endl;
    vek.insert(vek.begin() + i + 1, -vek[i]);
  }
  std::cout << std::endl;
  for (int i: vek) std::cout << i << " ";
  return 0;
}

实际运行输出与预期不符:

1 2 3
0 1  // 预期应为0 1(因为vek[0]=1)
1 -1 // 预期应为1 2(因为vek[1]=2)
2 1  // 预期应为2 3(因为vek[2]=3)

1 -1 1 -1 2 3 // 预期应为1 -1 2 -2 3 -3
错误原因与实际运行逻辑

问题出在两个被忽略的特性和循环逻辑错误:

  • std::vector::insert的固有行为:向vector任意位置插入元素时,插入位置及之后的所有元素会整体向后顺移1位,vector总长度+1,元素下标会重新排列
  • 循环逻辑缺陷:原代码循环步长固定为+1、循环终止条件硬编码为i<3,完全没有考虑插入操作带来的元素位置偏移

逐轮拆解循环的实际执行过程:

  1. 循环启动前,vek长度为3,下标对应元素:0:1, 1:2, 2:3
  2. 第一轮i=0:取vek[0]=1,在下标1的位置插入-1。插入后元素顺移,vek长度变为4,元素为0:1, 1:-1, 2:2, 3:3,这一步输出符合预期
  3. 第二轮i=1:此时下标1的位置已经是上一轮插入的-1,不是原有的2。代码取vek[1]=-1,在下标2的位置插入-(-1)=1,插入后vek长度变为5,元素为0:1, 1:-1, 2:1, 3:2, 4:3,输出1 -1,和预期偏离
  4. 第三轮i=2:此时下标2的位置是上一轮插入的1,不是原有的3。代码取vek[2]=1,在下标3的位置插入-1,插入后vek长度变为6,元素为0:1, 1:-1, 2:1, 3:-1, 4:2, 5:3,输出2 1,完全偏离预期
  5. 循环结束,最终遍历输出的结果就是1 -1 1 -1 2 3,和实际运行结果一致。
修复方案

不需要引入额外数据结构,只需要调整循环逻辑:记录vector初始的元素个数作为循环总次数,每次插入完成后,通过偏移计算定位下一个待处理的原元素下标即可。

修复后的可运行代码:

#include <iostream>
#include <vector>
int main() {
  std::vector < int > vek {1,2,3};
  // 记录初始元素个数,只需要处理原有元素
  int original_len = vek.size();
  for (int i = 0; i < original_len; i++) {
    // 每插入一个元素,后续原元素位置后移2位,用2*i定位当前待处理原元素的下标
    vek.insert(vek.begin() + 2*i + 1, -vek[2*i]);
  }
  // 验证输出
  for (int i: vek) std::cout << i << " "; // 输出1 -1 2 -2 3 -3,符合预期
  return 0;
}

内容的提问来源于stack exchange,提问作者Rocket Procd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:27:29