【问题标题】:Remove one random element from each row and column in a Sudoku matrix从数独矩阵的每一行和每一列中删除一个随机元素
【发布时间】:2017-09-13 23:17:29
【问题描述】:

在上一篇文章中,我提到了如何从数独矩阵的每一行中删除一个元素。现在,我正在考虑从数独矩阵中删除一个元素的方法,但要针对每一行和每一列。我正在考虑创建一个数组来存储列索引,如果元素在行中被删除。然后在下一行中您是否迭代以删除另一个元素检查以查看您删除的数字是否在先前存储的列索引中。虽然我不认为这将是一个非常有效的算法。

从行方法中移除元素

public static void remove_Sud (int [][] S){ // Remove sudoku method 
    for(int i = 0; i < S.length; i++){ // For loop iterate through length of matrix array
        int randomPosition = (int) Math.floor(Math.random() * S.length);  //Random number between 0 and 2
        S[i][randomPosition] = 0; // 0 or whatever you use to represent blank
    }

}

Sudoku Matrix

【问题讨论】:

  • 您有问题吗?
  • 如何从数独矩阵的每一行和每一列中删除一个元素?
  • 我在下面发布了一个可能有用的答案。

标签: java matrix sudoku


【解决方案1】:

您可以使用此代码。我没有用完美的数独值制作矩阵,但你可以看到输出。函数是deleteRandom()

8 1 5 4 2 5 3 0 2 1 
3 6 0 4 5 5 3 3 5 8 
6 9 4 3 8 2 3 8 0 7 
2 9 9 1 0 5 7 6 9 2 
4 0 6 7 7 9 5 6 6 2 
2 9 1 8 8 7 9 9 8 0 
0 4 6 2 7 3 8 5 8 1 
1 8 5 2 1 8 0 4 8 7 
4 7 5 0 6 6 6 4 3 3 
9 6 3 5 6 0 4 7 1 6 

每一行每一列只有一个零,每次程序执行都会改变。

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Random;
import java.util.Set;

public class test {
    public static void main(String[] args) {
        int[][] sodoku = new int[10][10];
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                Random random = new Random();
                int max = 9;
                int min = 1;
                sodoku[i][j] = random.nextInt(max - min + 1) + min;
            }
        }
        print(sodoku);
        deleteRandom(sodoku);
    }

    private static void deleteRandom(int[][] sodoku) {
        Random r = new Random();
        Set<Integer> rowSet = new LinkedHashSet<>();
        while (rowSet.size() != 10) {
            int answer = r.nextInt(10);
            rowSet.add(answer);
        }
        ArrayList<Integer> rowList = new ArrayList<>();
        rowList.addAll(rowSet);

        Set<Integer> colSet = new LinkedHashSet<>();
        while (colSet.size() != 10) {
            int answer = r.nextInt(10);
            colSet.add(answer);
        }
        ArrayList<Integer> colList = new ArrayList<>();
        colList.addAll(colSet);
        for (int i = 0; i < 10; i++) {
            sodoku[rowList.get(i)][colList.get(i)] = 0;
        }
        System.out.println();
        print(sodoku);
    }

    private static void print(int[][] sodoku) {
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                System.out.print(sodoku[i][j] + " ");
            }
            System.out.println();
        }
    }
}

【讨论】:

    【解决方案2】:

    为了有效地做到这一点,我建议创建两个索引数组(一个用于列,一个用于行),每个 9 int 长。它比使用列表更有效。然后我们用 0-8 的整数排列填充它们而不重复,并将它们用作矩阵中哪些元素输入 0 的映射。

    这是一个示例代码:

    public static void removeSudoku(int[][] sudoku) {
        Random rand = new Random();
        int[] cols = {-1,-1,-1,-1,-1,-1,-1,-1,-1};
        int[] rows = {-1,-1,-1,-1,-1,-1,-1,-1,-1};
    
        //We need to choose an index for each number 0-8 inclusive.
        for (int i=0;i<9;i++) {
    
          //get a random index on the column array for i
          int randomInt = rand.nextInt(9);
          //In case this random index is already populated - 
          //rand again until an empty spot is available.
          while (cols[randomInt]!=-1) {
            randomInt = rand.nextInt(9);
          }
          cols[randomInt] = i;
    
          //Same thing for the rows - get a random index in the 
          //array for i, rand again if needed.
          randomInt = rand.nextInt(9);
          while (rows[randomInt]!=-1) {
            randomInt = rand.nextInt(9);
          }
          rows[randomInt] = i;
        }
    
        //Now that we have the two arrays filled in with a random
        //permutation of ints 0-8, we can use it to remove the 
        //elements from the sudoku.
        for (int i=0;i<9;i++) {
          sudoku[rows[i]][cols[i]] = 0;
        }
      }
    
      //Just for printout
      public static void printSoduku(int[][] sudoku) {
        for (int i=0;i<9;i++) {
          for(int j=0;j<9;j++) {
            System.out.print(sudoku[i][j]+" ");
            if (j==2 || j==5) {
              System.out.print("|");
            }
          }
          System.out.println();
          if (i==2 || i==5) {
            System.out.println("-------------------");
          } 
        }
      }
    
      public static void main(String[] args) throws IOException {
    
        int[][] soduku = new int[][] {{1,2,3,4,5,6,7,8,9},
        {4,5,6,7,8,9,1,2,3},{7,8,9,1,2,3,4,5,6},
        {2,3,4,5,6,7,8,9,1},{5,6,7,8,9,1,2,3,4},
        {8,9,1,2,3,4,5,6,7},{3,4,5,6,7,8,9,1,2},
        {6,7,8,9,1,2,3,4,5},{9,1,2,3,4,5,6,7,8}};
        printSudoku(sudoku);
        removeSudoku(sudoku);
        System.out.println();
        printSudoku (sudoku);
      }
    

    输出将是原始数独矩阵,然后是删除的:

    1 2 3 |4 5 6 |7 8 9 
    4 5 6 |7 8 9 |1 2 3 
    7 8 9 |1 2 3 |4 5 6 
    -------------------
    2 3 4 |5 6 7 |8 9 1 
    5 6 7 |8 9 1 |2 3 4 
    8 9 1 |2 3 4 |5 6 7 
    -------------------
    3 4 5 |6 7 8 |9 1 2 
    6 7 8 |9 1 2 |3 4 5 
    9 1 2 |3 4 5 |6 7 8 
    
    1 2 3 |0 5 6 |7 8 9 
    4 5 6 |7 8 9 |0 2 3 
    0 8 9 |1 2 3 |4 5 6 
    -------------------
    2 3 0 |5 6 7 |8 9 1 
    5 6 7 |8 0 1 |2 3 4 
    8 9 1 |2 3 0 |5 6 7 
    -------------------
    3 0 5 |6 7 8 |9 1 2 
    6 7 8 |9 1 2 |3 4 0 
    9 1 2 |3 4 5 |6 0 8 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-27
      • 2012-12-11
      • 1970-01-01
      • 2018-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多