我有一个包含正整数和负整数的int[][][]a。我只想将正整数复制到另一个数组中,int[][]result。这是我的尝试:
for( int r = 0; r < a.length; r ++ )
{
int aC = 0;
for( int resC = 0; resC < result[r].length; resC++ )
{
while (a[r][aC] < 0)
{
aC++;
}
result[r][resC] = a[r][aC];
aC++;
}
}
当我运行程序时,它在第6行崩溃,引用了一个java.lang.ArrayIndexOutOfBoundsException: 3
错误。当我运行调试器时,我可以看到只要r=0,它就可以工作。
我觉得我错过了一些显而易见的东西,但盯着它看了一个小时后,我仍然找不到问题所在。
为什么有3个循环?只需循环2个维度并复制正值:
for (int r = 0; r < a.length; r++)
for (int c = 0; c < a[r].length; c++)
if (a[r][c] > 0)
result[r][c] = a[r][c];
当然,除非你想浓缩这些值(问题没有说,但代码尝试似乎表明了这一点)。或者您也想截断?
Input Copy Condensed Truncated
-1 1 2 0 1 2 1 2 0 1 2
-1 -1 3 ==> 0 0 3 ==> 3 0 0 ==> 3
4 -1 5 4 0 5 4 5 0 4 5
这里有一个截断的版本:
int[][] result = new int[a.length][];
for (int r = 0; r < a.length; r++) {
int count = 0;
for (int c = 0; c < a[r].length; c++)
if (a[r][c] > 0)
count++;
result[r] = new int[count];
for (int c = 0, cRes = 0; c < a[r].length; c++)
if (a[r][c] > 0)
result[r][cRes++] = a[r][c];
}
当我们到达内部CCD_ 2循环时,我们对CCD_ 3没有任何保证,因此CCD_ 4很可能是越界的。取而代之的是:
for (int r = 0; r < a.length; r++) { int aC = 0; for (int resC = 0; resC < result[r].length; resC++) {
代码将更安全,如下所示:
for (int r = 0; r < a.length; r++) {
int aC = 0;
for (int resC = 0; resC < a[r].length; resC++) {
因为,我们知道a[r]
将在边界内。
但这还远远不够。最里面的while
循环也可能试图访问越界的索引,事实上,当您至少有一个负值时,这是不可避免的。实际上,你需要反转那里的循环逻辑,而不是在结果中对索引进行迭代,对源代码中的索引进行迭代会更有意义。像这样:
for (int r = 0; r < a.length; r++) {
int resC = 0;
for (int aC = 0; aC < a[r].length; aC++) {
if (a[r][aC] < 0) {
continue;
}
result[r][resC++] = a[r][aC];
}
}
最后,通过重命名变量,可以更容易地理解代码试图做什么:
for (int row = 0; row < source.length; row++) {
int targetCol = 0;
for (int col = 0; col < source[row].length; col++) {
if (source[row][col] < 0) {
continue;
}
target[row][targetCol++] = source[row][col];
}
}
在上没有边界检查
a[r][aC]
所以
while (a[r][aC] < 0)
将失败。
同样,由于现在的数组大小不均匀,最好将其添加到ArrayList中,然后在必要时转换为数组。
类似的东西
ArrayList <Integer> posValues = new ArrayList <Integer> ();
for( int r = 0; r < a.length; r ++ )
{
for( int c = 0; c < a[r].length; c++ )
{
if (a[r][c] > 0)
{
posValues.add (new Integer (a[r][c]));
}
}
}