Java - 2D布尔数组中的计数保持为false

时间:2018-04-06 14:04:59

标签: java arrays

我有一个2D布尔数组数组,我希望计算一个规则相对于行或列具有true的位置时的错误剩余数。

如果一行或一列有一个真值,那么我需要减少二维数组中错误出现次数的数量,其中出现真实的行和列。

e.g。

如果第一行和列矩阵[0] [0]中的真实欠费以及矩阵[0] [j]和矩阵[i] [0]中的所有其他条目都为假,那么我需要排除那些错误虚假剩余的数量。

    [0],  [1]
[0] TRUE, FALSE
[1] FALSE FALSE

因此,当我应用规则时,只有一个错误,其行或列中没有true,即matrix [1] [1]。

我不能概括循环迭代,它在某些情况下有效但在其他情况下无效。下面的前两个例子是正确的,但第三个例子不正确,因为它应该是6而不是4。

我可以看到的原因是在第三个数组中有一个 true 位于同一列(matrix3 [2] [4])(在matrix3中突出显示)已被淘汰计算所以答案会减少两倍。

有没有办法可以跟踪已经从计数中取出的列和行?

public class CountRemainingFalse {
    public int countRemainingFalse (int n, boolean[][] matrix) {
        int count = n * n;

        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix.length; j++) {
                if (matrix[i][j]) {
                    count = count - (2 * n - 1);
                    n--;
                    break;
                }
            }
        }
        return count;
    }
}

class CountFalseRemainingApp {
    public static void main(String[] args) {
        CountRemainingFalse crf = new CountRemainingFalse();

        boolean matrix1[][] = {
                {false, false, false, false, false, false},
                {false, false, true, true, false, false},
                {false, false, true, true, false, false},
                {false, false, false, false, false, false},
                {false, false, false, false, false, false},
                {false, false, false, false, false, false} };

        boolean matrix2[][] = {
                {false, false, false, false, true, false},
                {false, false, true, true, false, false},
                {false, false, true, true, false, false},
                {false, false, false, false, false, false},
                {false, false, false, false, false, false},
                {false, false, false, false, false, false} };

        boolean matrix3[][] = {
                {false, false, false, false, true, false},
                {false, false, false, true, false, false},
                {false, false, false, false, **true**, false},
                {false, true, false, false, false, false},
                {false, false, false, false, false, false},
                {false, false, false, false, false, false} };


        System.out.println(crf.countRemainingFalse(6, matrix1));
        System.out.println(crf.countRemainingFalse(6, matrix2));
        System.out.println(crf.countRemainingFalse(6, matrix3));
    }
}

输出是:

16 // correct
9  // correct
4  // incorrect should be 6 (matrix3[0][4] was already accounted for but matrix3[2][4] also has a true)

2 个答案:

答案 0 :(得分:1)

你可以做两次通过,第一部分找出禁止的行和列,第二次通过计数:

boolean[] bannedRows = new boolean[n];
boolean[] bannedColumns = new boolean[n];
for (int i = 0; i < n; i++) {
  for (int j = 0; j < n; j++) {
    if (matrix[i][j]) {
      bannedRows[i] = true;
      bannedColumns[j] = true;
    }
  }
}
int count = 0;
for (int i = 0; i < n; i++) {
  for (int j = 0; j < n; j++) {
    if (!bannedRows[i] && !bannedColumns[j]) {
      count++;
    }
  }
}
return count;

编辑:关于过早优化的说明:首选简单,明显正确的代码,而不是不必要的优化代码,如果它是正确的,难以阅读和难以理解。一旦迫切需要优化并且您已经验证此功能是导致缓慢的原因,则进行优化

答案 1 :(得分:0)

您可以使用布尔数组来跟踪列。我相信当你的矩阵列中有多个true时,你的代码会遇到你所说的问题。该数组与列的大小相同,当您遇到true时,将数组中的值设置为true。所以这样,一旦你遇到同一列中出现的另一个true,代码就不会执行。

以下是一个示例实现:

boolean[] alreadyPresent = new boolean[matrix[0].length];    
for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix.length; j++) {
            if (matrix[i][j] && !alreadyPresent[j]) {
                alreadyPresent[j] = true;
                count = count - (2 * n - 1);
                n--;
                break;
            }
        }
    }
    return count;
}