如何用整数二进制表示过滤数组?Java代码调试求助
问题排查与修复方案
嘿,我来帮你拆解下代码里的问题,看看为什么会得到[18,18,18]而不是预期的[0,9,18]:
核心错误1:结果数组的填充逻辑完全错了
你填充筛选结果数组z的嵌套循环逻辑有大问题:
for (int i = 0; i < z.length; i++) { for (int k = 0; k < x.length; k++) { if(x[k] == 1) { z[i] = a[k]; } } }
这段代码的问题在于,每一次外层循环(i)都会把所有符合条件的a[k]依次赋值给z[i],最后z[i]会被最后一个符合条件的元素覆盖。比如你的测试用例里,符合条件的索引是0、1、3,所以每次i循环结束后,z[i]都会被最后一个符合条件的a[3] = 18覆盖,最终整个数组全是18。
正确的做法是用一个单独的指针记录z的当前填充位置,遍历二进制位时,遇到1就把对应a[k]放进z并移动指针:
int zIndex = 0; for (int k = 0; k < x.length; k++) { if (x[k] == 1) { z[zIndex++] = a[k]; } }
核心错误2:返回了完全不符合要求的数组
你的方法最后返回的是存储二进制位的x数组,而不是咱们辛辛苦苦筛选出来的z数组,这直接违背了题目要求。
缺失的关键检查:数组长度是否足够
题目明确要求:如果数组长度不足以容纳所有选中元素,返回null。比如如果n的二进制里有位的索引超过了a的长度(比如n=16即第4位为1,但a只有5个元素,索引最大是3),这时候必须返回null,但你的代码完全没做这个判断。
额外优化:去掉冗余的二进制存储数组
你创建了长度为a.length的x数组来存二进制位,但其实可以直接遍历n的二进制位处理,不用额外数组,既省空间又更高效。
修复后的完整代码
import java.util.Arrays; public class FilterArray { public static int[] filterArray(int[] a, int n) { int count = 0; int tempN = n; int bitPos = 0; // 第一步:统计符合条件的元素数量,同时检查索引是否越界 while (tempN > 0) { if ((tempN & 1) == 1) { count++; // 如果当前位的索引超过数组长度,直接返回null if (bitPos >= a.length) { return null; } } tempN >>= 1; bitPos++; } // 第二步:创建结果数组并填充 int[] result = new int[count]; int resIndex = 0; tempN = n; bitPos = 0; while (tempN > 0) { if ((tempN & 1) == 1) { result[resIndex++] = a[bitPos]; } tempN >>= 1; bitPos++; } return result; } // 测试用例 public static void main(String[] args) { int[] testArr = {0,9,12,18,-6}; int n = 11; System.out.println(Arrays.toString(filterArray(testArr, n))); // 输出 [0, 9, 18] } }
修复后的代码说明
- 索引越界检查:遍历
n的每一位二进制位,只要某一位为1且对应的索引超过数组长度,直接返回null,满足题目要求。 - 正确填充结果:用
resIndex指针跟踪结果数组的填充位置,每遇到二进制位为1的情况,就把对应索引的a元素放入结果数组,避免了覆盖问题。 - 高效无冗余:直接操作二进制位,不用额外存储数组,性能更优。
- 返回正确结果:最后返回的是筛选后的结果数组,符合方法签名要求。
现在测试你的用例,就能得到正确的[0,9,18]了~
内容的提问来源于stack exchange,提问作者Samuel Mideksa
相关产品推荐
相关产品推荐

