如何从Java中的二维数组中删除占位符值?

时间:2016-05-13 07:26:49

标签: java arrays

我有一个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 个答案:

答案 0 :(得分:2)

为什么有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];
}

答案 1 :(得分:0)

你没有检查界限

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]));
            }
        }
 }

答案 2 :(得分:0)

当我们到达内部for循环时, 我们对result[r]没有任何保证, 所以r很可能是出界的。 而不是:

    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];
        }
    }