Java实现两个数组对称差时仅完成去重未得到正确结果的问题排查
问题分析与修正方案
嘿,我来帮你排查代码里的问题~你的思路方向是对的,但在相邻元素移除的逻辑和循环控制上出了问题,导致没能正确移除同时出现在两个数组里的元素。
你的代码核心问题
1. 移除重复元素时的索引偏移错误
当你调用symdifar.remove(i)后,ArrayList里的所有元素会向前移动一位——原来位于i+1的元素现在会跑到i的位置。这时候你再调用symdifar.remove(i+1),删掉的根本不是原来那个重复的元素,而是更后面的元素。比如:
假设排序后的列表是[1,2,2,3,3,4],当i=1时,你先remove(1),列表变成[1,2,3,3,4],再remove(2)就删掉了第一个3,最终剩下[1,2,3,4],这就是你得到错误结果的原因。
2. 循环的条件与递增逻辑错误
你用固定的n来控制循环,但ArrayList的长度在移除元素后会实时变化,n没有同步更新,导致循环提前结束。另外,不管有没有移除元素,你都让i++——如果移除了元素,当前i位置的新元素还需要和下一个元素比较,不能直接递增。
修正后的代码
我帮你调整了循环部分的逻辑,同时优化了数组转ArrayList和返回值的写法:
import java.util.ArrayList; import java.util.Arrays; public class SymmetricDifference { // 类名首字母大写,符合Java规范 public Integer[] symdif(int[] ar1,int[] ar2){ // 合并两个数组 int[] result = new int[ar1.length + ar2.length]; System.arraycopy(ar1, 0, result, 0, ar1.length); System.arraycopy(ar2, 0, result, ar1.length, ar2.length); // 排序 Arrays.sort(result); // 数组转ArrayList,简化写法 ArrayList<Integer> symdifar = new ArrayList<>(); for (int num : result) { symdifar.add(num); } // 修正后的循环逻辑 int i = 0; // 用实时的size判断循环条件,避免固定值失效 while (i < symdifar.size() - 1) { if (symdifar.get(i).equals(symdifar.get(i+1))) { // 先移除i+1,再移除i,避免索引偏移 symdifar.remove(i+1); symdifar.remove(i); // 移除后不递增i,因为当前位置的新元素需要重新检查 } else { // 元素不重复时,再移动到下一个位置 i++; } } // 返回Integer[]而非Object[],类型更安全 return symdifar.toArray(new Integer[0]); } public static void main(String[] args) { int[] array1 = {1,2,3}; int[] array2 = {2,3,4}; SymmetricDifference ob = new SymmetricDifference(); System.out.println(Arrays.toString(ob.symdif(array1,array2))); } }
额外建议(适合新手进阶)
其实Java的集合框架可以更简洁地实现对称差,比如用HashSet:
import java.util.HashSet; import java.util.Set; public class SymmetricDifference { public static Integer[] symdifWithSet(int[] ar1, int[] ar2) { Set<Integer> set1 = new HashSet<>(); for (int num : ar1) set1.add(num); Set<Integer> set2 = new HashSet<>(); for (int num : ar2) set2.add(num); // 复制set1作为基础,移除和set2的交集 Set<Integer> symmetricDiff = new HashSet<>(set1); symmetricDiff.removeAll(set2); // 再把set2中不在set1里的元素加进来 set2.removeAll(set1); symmetricDiff.addAll(set2); return symmetricDiff.toArray(new Integer[0]); } public static void main(String[] args) { int[] array1 = {1,2,3}; int[] array2 = {2,3,4}; System.out.println(Arrays.toString(symdifWithSet(array1, array2))); } }
这种方式不需要排序和手动遍历移除,利用集合的特性就能轻松实现,代码可读性更高~
内容的提问来源于stack exchange,提问作者fiocotti
相关产品推荐
相关产品推荐

