Java实现整数数组压缩(零值移至末尾)的代码逻辑求解
现有代码的核心错误
- 元素移动逻辑耦合在输入循环内:刚读入当前索引的元素就尝试操作后一位元素,当i取到数组最大索引(如长度为5时i=4),访问
v[i+1]会直接触发数组索引越界异常。 - 移动逻辑完全不符合需求:遇到0就将后一位元素赋值为0,本质是直接覆盖后续的有效元素,完全无法实现非0元素前移的效果。
- 边界判断分支的
v[i]=v[i]是无意义的自赋值操作,没有任何实际作用。
正确实现逻辑
不要在读取输入阶段处理数组压缩,先完成所有元素的读入,再单独执行压缩操作,全程不需要额外开辟数组空间,两次遍历即可完成:
- 维护一个非零元素写入位置的指针,初始值为0。第一次遍历全数组,遇到非0元素就将该元素写入指针对应的数组位置,同时指针后移一位。本轮遍历结束后,指针前的所有位置已经按原顺序存放了全部非0元素。
- 第二轮遍历从指针当前位置开始,走到数组末尾,将这些位置全部赋值为0,即可实现所有0移动到数组末尾的压缩效果。
该方案时间复杂度为O(n),无越界风险。
修正后的完整代码
保留原代码中的葡萄牙语交互提示,测试阶段用长度为5的数组,完成习题时直接将数组长度改为50即可:
import java.util.Scanner; public class ZeroMove { public static void main(String[] args) { Scanner s = new Scanner(System.in); // 习题要求长度为50时,将此处的5替换为50即可 int v[] = new int[5]; // 单独完成数组输入 for(int i = 0; i < v.length; i++){ System.out.println("Digite um valor"); v[i] = s.nextInt(); } // 非0元素前移 int nonZeroPos = 0; for (int i = 0; i < v.length; i++) { if (v[i] != 0) { v[nonZeroPos] = v[i]; nonZeroPos++; } } // 末尾补0 for (int i = nonZeroPos; i < v.length; i++) { v[i] = 0; } // 输出处理后的数组 for(int i = 0; i < v.length; i++){ System.out.println(v[i]); } s.close(); } }
效果验证
测试输入序列为0,2,0,4,5时,处理后的输出为2,4,5,0,0,非0元素相对顺序不变,所有0全部移动到数组末尾,完全符合习题要求。
内容的提问来源于stack exchange,提问作者AriadneWeb
相关产品推荐
相关产品推荐

