Java提取两随机整数数组交集差集时如何去除冗余占位0值
问题根源
- 你在初始化交集数组时直接分配了和a、b相同的固定长度(10位),Java中int类型数组的默认初始值为0,未被写入有效元素的位置会自动填充0。由于0本身是你要求的合法生成值,这类占位值会和真实的0元素完全混淆。
- 现有提取交集的逻辑存在索引错用问题:匹配到
a[k] == b[l]时直接用b的遍历下标l作为数组s的存储位置,会导致有效元素散落在数组各处,剩余位置全部留默认0。 - 附带的实现bug:
- 随机数生成范围错误:
(int) (Math.random() * (max - min))实际只能生成019的整数,无法覆盖要求的020全区间 - 重复值校验逻辑漏洞:内层循环触发
i--重生成随机数后,未对新生成的数做全量重复校验,很容易出现同数组内重复元素
- 随机数生成范围错误:
实现无冗余目标数组的方法
放弃一开始就固定目标数组长度的思路,采用「动态存有效元素→转定长数组」的流程:
- 用可自动扩容的
ArrayList<Integer>作为临时存储容器,只把符合交集/独有元素规则的值加入列表,列表长度会自动匹配有效元素的实际数量,不存在默认占位值 - 收集完成后,再把列表中的元素逐个写入等长的int数组,最终生成的数组长度和有效元素数量完全一致,没有冗余位置
这种实现下,数组的所有位置都存储有效元素,哪怕0是交集或独有元素,也不会出现占位0和真实值混淆的问题。
修正后的可运行代码
import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class P02ArraysExtractUniqsAndReps { public static void main(String[] args) { int nbr = 10; int min = 0; int max = 20; generateArray(nbr, min, max); } public static void generateArray(int nbr, int min, int max) { int[] a = generateUniqueRandomArr(nbr, min, max); int[] b = generateUniqueRandomArr(nbr, min, max); // 按要求格式输出a、b System.out.println("a -> " + Arrays.toString(a)); System.out.println("b -> " + Arrays.toString(b)); // 动态收集交集元素 List<Integer> intersectionList = new ArrayList<>(); for (int num : a) { if (hasValue(b, num)) { intersectionList.add(num); } } // 动态收集独有元素(a、b中不在交集里的所有元素) List<Integer> uniqueList = new ArrayList<>(); for (int num : a) { if (!intersectionList.contains(num)) { uniqueList.add(num); } } for (int num : b) { if (!intersectionList.contains(num)) { uniqueList.add(num); } } // 将动态列表转为定长int数组,无占位元素 int[] intersection = listToArray(intersectionList); int[] uniqueArr = listToArray(uniqueList); // 按要求格式输出目标数组 System.out.println("公共交集元素数组 -> " + Arrays.toString(intersection)); System.out.println("非公共独有元素数组 -> " + Arrays.toString(uniqueArr)); } // 生成指定长度、指定区间不重复随机数的数组 private static int[] generateUniqueRandomArr(int nbr, int min, int max) { int[] arr = new int[nbr]; for (int i = 0; i < nbr; ) { // 修正随机数范围,覆盖min~max闭区间 int randomNum = (int) (Math.random() * (max - min + 1) + min); if (!hasValue(arr, randomNum)) { arr[i] = randomNum; i++; } } return arr; } // 把Integer列表转为定长int数组 private static int[] listToArray(List<Integer> list) { int[] res = new int[list.size()]; for (int i = 0; i < list.size(); i++) { res[i] = list.get(i); } return res; } public static boolean hasValue(int[] array, int value) { for (int i = 0; i < array.length; i++) { if (array[i] == value) { return true; } } return false; } }
运行效果示例
a -> [13, 2, 0, 7, 19, 10, 5, 15, 4, 11] b -> [6, 17, 2, 1, 9, 10, 3, 14, 18, 0] 公共交集元素数组 -> [2, 0, 10] 非公共独有元素数组 -> [13, 7, 19, 5, 15, 4, 11, 6, 17, 1, 9, 3, 14, 18]
内容的提问来源于stack exchange,提问作者Gabriel Fidalgo
相关产品推荐
相关产品推荐

