[英]How do I remove placeholding values from a two dimensional array in Java?
I have an int[ ][ ] a that contains both positive and negative integers. 我有一个包含正负两个整数的int [] [] a。 I want to copy only the positive integers into another array, int[ ][ ] result. 我只想将正整数复制到另一个数组int [] []结果中。 Here's my attempt: 这是我的尝试:
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++;
}
}
When I run the program it crashes on line 6 quoting a java.lang.ArrayIndexOutOfBoundsException: 3
error. 当我运行该程序时,它在第6行崩溃,引用java.lang.ArrayIndexOutOfBoundsException: 3
错误。 When I run the debugger I can see that it works so long as r = 0. 当我运行调试器时,我看到只要r = 0,它就可以工作。
I feel like I'm missing something blindingly obvious but after staring at it for an hour I still can't find the problem. 我感觉好像缺少了令人眼花obvious乱的东西,但是凝视了一个小时之后,我仍然找不到问题。
Why have 3 loops? 为什么有3个循环? Just loop your 2 dimensions and copy positive values: 只需循环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];
Unless of course you want to condense the values (question didn't say, but code attempt seems to indicate). 除非您当然要压缩这些值(问题没有说,但是代码尝试似乎表明了这一点)。 Or did you also want to truncate? 还是您也想截断?
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
Here is a version with truncation: 这是带有截断的版本:
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];
}
You have no bounds checking on 你没有界限检查
a[r][aC]
so 所以
while (a[r][aC] < 0)
will fail. 将失败。
Also as you will now have uneven sized arrays, it would be better to to add to an ArrayList, and then convert to an array afterwards if necessary. 同样,由于您现在将拥有大小不均的数组,因此最好将其添加到ArrayList中,然后在必要时再转换为数组。
Something like 就像是
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]));
}
}
}
When we reach the inner for
loop, we don't have any guarantees about result[r]
, and so r
may very well be out of bounds. 当我们到达内部的for
循环时,就没有关于result[r]
任何保证,因此r
可能会超出范围。 Instead of this: 代替这个:
for (int r = 0; r < a.length; r++) { int aC = 0; for (int resC = 0; resC < result[r].length; resC++) {
The code will be safer like this: 这样的代码将更加安全 :
for (int r = 0; r < a.length; r++) {
int aC = 0;
for (int resC = 0; resC < a[r].length; resC++) {
Because, we know that a[r]
will be within bounds. 因为,我们知道a[r]
将在范围内。
But this is not nearly enough. 但这还远远不够。 The innermost while
loop is also likely to try to access an index out of bounds, in fact it's inevitable when you have at least one negative value. 最里面的while
循环也可能尝试超出范围访问索引,实际上,当您至少有一个负值时,这是不可避免的。 Actually you need to invert the looping logic there, instead of iterating over indexes in result, it will make more sense to iterate over indexes in the source. 实际上,您需要在此反转循环逻辑,而不是遍历结果索引,而遍历源代码中的索引将更有意义。 Like this: 像这样:
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];
}
}
Finally, with variables renamed, it becomes a lot easier to understand what the code is trying to do: 最后,通过重命名变量,可以更轻松地了解代码正在尝试执行的操作:
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];
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.