C++通过循环更新二维数组实现行水平翻转的问题排查
问题逻辑错误说明
你的核心错误是在原数组上直接遍历全量元素做覆盖赋值,没有提前保存原始值,导致前半段元素被覆盖后,后半段读取到的对称位置值已经被修改,不再是初始状态的原始值。
你之前打印「Future allocations」时结果符合预期,是因为那一步只做读取不做修改,拿到的全是数组初始值;一旦开始边读边改,数组里的值就会被逐步污染。
以第一行初始值[3,2,1]为例,逐轮执行你的赋值逻辑就能复现错误:
- j=0时:读取对称位置j=2的值是1,把
image[0][0]改成1,此时第一行变为[1,2,1],原始值3被直接覆盖丢失 - j=1时:对称位置是j=1本身,读取值为2,赋值后无变化,第一行保持
[1,2,1] - j=2时:对称位置是j=0,此时j=0位置的值已经被改成1,不是最初的3,赋值后
image[0][2]还是1,最终第一行结果就变成了错误的[1,2,1]
剩下两行的错误逻辑和第一行完全一致,才会出现每行最后一个元素不符合预期的现象。
修复方法
原地翻转数组不需要遍历整行所有元素,只需要遍历每行的前半段,交换对称位置的两个元素即可,从根源上避免值被提前覆盖的问题。修改后的值更新段代码如下:
//Updating values 修正版 cout << "\n\t\t Actual allocations: " << endl; int row_len = image[0].size(); for(int i = 0; i < image.size(); i++){ // 仅遍历行的前半段,到行长度一半位置就终止 for(int j = 0; j < row_len / 2; j++){ int mirror_pos = row_len - 1 - j; cout << "\nswap image[" << i << "][" << j << "] and image[" << i << "][" << mirror_pos << "]"; // 交换对称位置的两个元素 int temp = image[i][j]; image[i][j] = image[i][mirror_pos]; image[i][mirror_pos] = temp; } cout << "\n"; }
运行修正后的代码,最终输出结果就会符合预期:
1 2 3 4 5 6 7 8 9
如果你不想用交换写法,也可以先把每一行的原始值拷贝到临时数组中,再遍历全量元素从临时数组取值赋值给原数组,同样能解决值被覆盖的问题,只是会多占用一点临时内存。
内容的提问来源于stack exchange,提问作者Hxx
相关产品推荐
相关产品推荐

