【问题标题】:set value for random element on matrix设置矩阵上随机元素的值
【发布时间】:2016-10-22 03:09:59
【问题描述】:

我正在尝试生成一个 8 x 8 矩阵。矩阵的每个元素都需要有一个值为 1 的值,除了每一列上的一个元素设置为 0,通过生成 0-7 之间的随机 int 来选择一个元素。

我运行代码时得到的结果:

   1     1     1     1     1     1     1     1  
   1     1     1     0     1     1     1     1  
   1     1     0     1     1     1     1     1  
   1     0     1     1     1     1     1     1  
   1     0     1     1     1     1     1     1  
   1     0     0     1     1     1     1     1  
   1     1     1     1     1     1     1     1  
   1     1     1     1     1     0     1     1  

我的矩阵应该是这样的:

   1     1     1     1     1     1     1     1  
   1     1     0     1     1     1     1     1  
   1     1     1     1     1     0     1     0  
   0     1     1     1     1     1     1     1  
   1     1     1     0     1     1     0     1  
   1     0     1     1     1     1     1     1  
   1     1     1     1     1     1     1     1  
   1     1     1     1     0     1     1     1  

代码

    for (int[] row: grid)
        Arrays.fill(row, 1);

    for (int i=0; i<grid.length; i++) {
       int j = getRandom();
       grid[i][j] = 0;
    }

    // print matrix
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++)
            System.out.format("%2s%2d%2s", " ", Main.grid[i][j], " ");

        System.out.println();
    }

【问题讨论】:

  • 有什么问题?
  • @Alex 如果您运行代码,您会看到它跳过了一些列或在同一列中创建了两个 0 值。
  • 啊好的。这是因为您将这两个任务都放在最内层循环中,导致它们都在每个单元格中运行一次。您需要在每个单元格上将单元格设置为 1,但您只需每列选择一次 0
  • 请注意,您的第二个示例在所有 1 的行/行中都有重复
  • @Rogue OP 正在显示实际结果并将其与预期结果进行比较

标签: java for-loop matrix


【解决方案1】:

在您的嵌套循环中,单元格的初始化和归零都在最内层循环中。这将导致每个单元格都运行一次,但每列仅执行一次归零。

如果我们将单元格的初始化顺序从一行接一行更改为一列接一列,我们可以将清零逻辑移到最外层循环。

for (int c = 0; c < 8; c++) {
    for (int r = 0; r < 8; r++) {
        Main.grid[r][c] = 1;
    }

    Main.grid[getRandom()][c] = 0; // assuming your getRandom() is within range
}

【讨论】:

    【解决方案2】:

    首先让矩阵全为1:

    //fill however you like
    int[][] matrix = IntStream.range(0, 8).mapToObj(i
                     -> IntStream.range(0, 8).map(i -> 1).toArray());
    

    然后,根据您的问题,您似乎希望每列的唯一行为零。所以只需打乱你的列索引:

    List<Integer> rows = IntStream.range(0, 8).collect(Collectors.toList());
    Collections.shuffle(rows); //random rows per 0-8 column
    AtomicInteger column = new AtomicInteger();
    //iterate columns, and select random row
    rows.forEach(i -> matrix[i][column.getAndIncrement()] = 0);
    

    这会将随机 0 分散为每行(和每列)唯一,并且实际上不涉及任何 RNG,所以它是 O(n)

    【讨论】:

      【解决方案3】:

      首先,使用 Arrays.fill api,它会让你的代码更加简洁。

      int[][] matrix = new int[m][n];
      // Fill each row with 1
      for (int[] row: matrix)
          Arrays.fill(row, 1);
      

      然后,对于每一行,随机选择一个列号并插入“0”,从而替换 1。

      for(int i=0; i<matrix.length; i++) {
         int j = Math.Random(0,matrix[0].length); // Or any other api for random number generation
         matrix[i][j] = 0;
      }
      

      【讨论】:

      • 不幸的是我仍然有同样的问题。有些列没有 0 就被跳过,有些列有多个 0。我更新了代码。
      猜你喜欢
      • 1970-01-01
      • 2014-10-22
      • 2014-09-19
      • 2017-02-17
      • 1970-01-01
      • 2020-07-13
      • 2015-09-06
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多