如何检查数独是否有效

How to check if sudoku is valid or not

我写了一个 java 程序来检查数独解法是否有效,但它不起作用,

它给出的所有值都是假的,根据我的程序逻辑是正确的。

我想在没有哈希集的情况下以最简单的方式执行此操作,因此我使程序非常简单,请不要建议哈希集或任何东西,但它仍然无法正常工作。任何有关如何修复此程序的建议都会有很大帮助。

import java.util.*;

class sudoku {
private int[][] sudoku;
public sudoku() {
    sudoku = new int[9][9];
}
public sudoku(int sudoku[][]) {
    this.sudoku = sudoku;
}
private boolean containsInRow(int row, int number) {

    for (int i = 0; i < 9; i++) {
        if (sudoku[row][i] == number) {


            return true;
        }
    }
    return false;
}
private boolean containsInCol(int col, int number) {

    for (int i = 0; i < 9; i++) {

        if (sudoku[i][col] == number) {

            return true;
        }
    }
    return false;
}

private boolean containsInBox(int row, int col, int number) {

    int r = row - row % 3;
    int c = col - col % 3;
    for (int i = r; i < r + 3; i++) {
        for (int j = c; j < c + 3; j++) {
            if (sudoku[i][j] == number) {


                return true;
            }
        }

    }
    return false;
}

private boolean isAllowed(int row, int col, int number) {
boolean checkforCol = containsInCol(col, number);
boolean checkforBox = containsInBox(row, col, number);
boolean checkforRow = containsInRow(row, number);



    return !( checkforBox || checkforCol || checkforRow);
}

public static void main(String ar[]) {
    Scanner sc = new Scanner(System.in);
    int count = 0;


    int[][] board = 
    {
    {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,1  ,5,6,4, 8,9,7},
    {5,6,4  ,8,9,7, 2,3,1},
    {8,9,7  ,2,3,1, 5,6,4},
    
    {3,1,2  ,6,4,5, 9,7,8},
    {6,4,5  ,9,7,8, 3,1,2},
    {9,7,8  ,3,1,2, 6,4,5}
   };
    sudoku a = new sudoku(board);
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            boolean c = a.isAllowed(i, j, board[i][j] ) ;

           if(c == true) {
               count++;
           }

        }
    }
    if(count == 81) {
    System.out.print("Valid");
    }
    else {
    System.out.print("Invalid");
    }
}

}

在行、列和框的检查函数中,您正在检查它是否包含数字。 Whick 总是正确的,因为您也在检查您的号码中的大小写。

您应该在 isAllowed 和 checksCol Row and Box 中跳过您正在检查的数字中的大小写,或者更改您的检查函数以使其计算数字的出现次数,如果每个数字只出现一次,则在 isAllowed 中进行检查。

像这样:

import java.util.*;

class sudoku {
    private int[][] sudoku;
    public sudoku() {
        sudoku = new int[9][9];
    }
    public sudoku(int sudoku[][]) {
        this.sudoku = sudoku;
    }
    private int containsInRow(int row, int number) {
        int c = 0;
        for (int i = 0; i < 9; i++) {
            if (sudoku[row][i] == number) {
            c++;    
            }
        }
        return c;
    }
    private int containsInCol(int col, int number) {
        int c = 0;
        for (int i = 0; i < 9; i++) {
            if (sudoku[i][col] == number) {
                c++;
            }
        }
        return c;
    }
    private int containsInBox(int row, int col, int number) {
        int count = 0;
        int r = row - row % 3;
        int c = col - col % 3;
        for (int i = r; i < r + 3; i++) {
            for (int j = c; j < c + 3; j++) {
                if (sudoku[i][j] == number) {
                    count++;
                }
            }
        }
        return count;
    }
    private boolean isAllowed(int row, int col, int number) {
        int checkforCol = containsInCol(col, number);
        int checkforBox = containsInBox(row, col, number);
        int checkforRow = containsInRow(row, number);

        return !( (checkforBox!=1) || (checkforCol!=1) || (checkforRow!=1) );
    }
    public static void main(String ar[]) {
        Scanner sc = new Scanner(System.in);
        int count = 0;

        int[][] board = 
        {
        {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,1  ,5,6,4, 8,9,7},
        {5,6,4  ,8,9,7, 2,3,1},
        {8,9,7  ,2,3,1, 5,6,4},
    
        {3,1,2  ,6,4,5, 9,7,8},
        {6,4,5  ,9,7,8, 3,1,2},
        {9,7,8  ,3,1,2, 6,4,5}
        };
        sudoku a = new sudoku(board);
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                boolean c = a.isAllowed(i, j, board[i][j] ) ;
               if(c == true) {
                   count++;
               }
            }
        }
        if(count == 81) {
            System.out.print("Valid");
        }
        else {
            System.out.print("Invalid");
        }
    }
}

您需要检查一组 9 个 one-digit 个数字是否都是数字 1-9。

最简单的方法是使用 bit-manipulation,即设置与数字相关的位,结果必须是 0b1111111110,也就是 0x3FE,又名 01776,又名 1022

如果一个数字出现两次,那么另一个数字将丢失,即该位将是 0.

所以,例如

private boolean validRow(int row) {
    int bits = 0;
    for (int col = 0; col < 9; col++)
        bits |= 1 << sudoku[row][col];
    return bits == 0b1111111110;
}
private boolean validColumn(int col) {
    // TODO
}
private boolean validBox(int row, int col) {
    // TODO
}
private boolean validBoard() {
    for (int row = 0; row < 9; row++)
        if (! validRow(row))
            return false;
    // TODO Test columns
    // TODO Test boxes
    return true;
}