使用java程序帮你解数独

来源:互联网 发布:淘宝大v达人申请文章 编辑:程序博客网 时间:2024/04/30 21:02

相信数独大家都多少有玩过吧?就是一个3x3 的9个块、每块里面又是3x3的小块

使每行每列都填充1-9的数字且只能使用一次、一般期刊后面都会有数独小游戏的、

以前也玩过数独、但是太难的就不知道该怎么解了、


今天逛了外国网站、发现一解数独的小程序、偷拿来分享、


只使用了两个类  SudokuSolver 和  Grid 、


先贴源码:

SudokuSolver 


/** * This program is executed in the following way: *    java SudokuSolver <input-file> * For details of the input-file format, see the Grid.java class. * * @author  Patrick Chan * @version 1, 12/31/05 * @see Grid */import java.io.*;import java.util.*;public class SudokuSolver {    public static void main(String[] args) throws Exception {        // Open the file containing the givens    String arg = "C:/ad.txt";            //File file = new File(arg);        FileReader rd = new FileReader(arg);        // Process each grid in the file        while (true) {            Grid grid = Grid.create(rd);            if (grid == null) {                // No more grids                break;            }            // Find a solution            List<Grid> solutions = new ArrayList<Grid>();            solve(grid, solutions);            printSolutions(grid, solutions);        }    }    // Recursive routine that implements the bifurcation algorithm    private static void solve(Grid grid, List<Grid> solutions) {        // Return if there is already a solution        if (solutions.size() >= 2) {            return;        }        // Find first empty cell        int loc = grid.findEmptyCell();        // If no empty cells are found, a solution is found        if (loc < 0) {            solutions.add(grid.clone());            return;        }        // Try each of the 9 digits in this empty cell        for (int n=1; n<10; n++) {            if (grid.set(loc, n)) {                // With this cell set, work on the next cell                solve(grid, solutions);                // Clear the cell so that it can be filled with another digit                grid.clear(loc);            }        }    }    private static void printSolutions(Grid grid, List<Grid> solutions) {        // Print the grid with the givens        System.out.println("Original");        System.out.println(grid);        // Print the solution        if (solutions.size() == 0) {            System.out.println("Unsolveable");        } else if (solutions.size() == 1) {            System.out.println("Solved");        } else {            System.out.println("At least two solutions");        }        // Print the solution(s)        for (int i=0; i<solutions.size(); i++) {            System.out.println(solutions.get(i));        }        System.out.println();        System.out.println();    }}



和  Grid


/** * @author  Patrick Chan * @version 1, 12/31/05 * @see SudokuSolver */import java.io.Reader;/** * A Grid object holds the currently known values of the Sudoku puzzle. * The grid consists of 9x9 cells that hold integer values from 0 to 9. * A value of 0 indicates that the cell is empty. * * Each of the 81 cells has a location which is used to identify a * specific cell. There are 81 locations, labelled location 0 to location 80. * Cell locations are ordered from left-to-right and top-down. * For example, location 0 refers to the top-leftmost cell. * Location 8 refers to the top-righttmost cell. * Location 71 refers to the bottom-leftmost cell. * Location 80 refers to the bottom-rightmost cell. * * The grid consists of 9 columns, labelled column 0 to column 8. * The grid consists of 9 rows, labelled row 0 to row 8. * * The grid consists of 9 subgrids, labelled subgrid 0 to subgrid 8. * Each subgrid contains a subgrid of 3x3 cells. * Subgrid 0 contains cells - 0, 1, 2, 9, 10, 11, 18, 19, 20. * Subgrid 8 contains cells - 60, 61, 62, 69, 70, 71, 78, 79, 80 */public class Grid implements Cloneable {    // Array that contains values of all 81 cells in the grid.    int[] cells = new int[81];    // A set of bit-vectors that represent the known values for each column.    // Specifically, if column c contains the digits d1 and d2,    //   colsSet[c] = 2^(d1-1)|2^(d2-1)    // For example, if column 0 contains the values 1 and 4, colsSet[0] = 9.    // The information in this variable is redundant with the information    // in the cells variable. The purpose of this variable is to reduce    // the cost of determining whether a particular digit can be set in    // a particular cell.    int[] colsSet = new int[9];    // This purpose and behavior of this variable is similar to colsSet.    int[] rowsSet = new int[9];    // This purpose and behavior of this variable is similar to colsSet.    int[] subgridSet = new int[9];    /**     * This method returns a grid of givens and empty cells ready to be solved.     * The cells containing givens have values between 1 and 9.     * Empty cells have the value 0.     *     * Characters are read one at a time from the input stream and placed     * into the grid in left-to-right and top-down order.     * - The characters 0 or . indicates an empty cell.     * - The characters 1 to 9 indicates a given.     * - The character # is used for comments; subsequent characters are     *   ignored until a newline is encountered.     * - All other characters are simply ignored.     *     * @param     rd  Reader containing the givens     * @return    null if there are not enough characters in 'rd' to form a grid.     */    public static Grid create(Reader rd) throws Exception {        Grid grid = new Grid();        // Read until all 81 cells are filled        for (int loc=0; loc<grid.cells.length; ) {            // Read a character            int ch = rd.read();            // -1 is returned if the input stream has no more characters            if (ch < 0) {                // No more characters so return null                return null;            }            if (ch == '#') {                // Skip to end-of-line                while (ch >= 0 && ch != '\n' && ch != '\r') {                    ch = rd.read();                }            } else if (ch >= '1' && ch <= '9') {                // A given                grid.set(loc, ch-'0');                loc++;            } else if (ch == '.' || ch == '0') {                // Empty cell                loc++;            }        }        return grid;    }    /*     * Finds an empty cell.     * @return the location of an empty cell or -1 if there are no empty cells.     *         Values must be in the range [-1, 80].     */    public int findEmptyCell() {        for (int i=0; i<cells.length; i++) {            if (cells[i] == 0) {                return i;            }        }        return -1;    }    /*     * Sets a number in a cell. This method checks to see if     *   1. the cell is empty     *   2. the cell is allowed to contain the specified number. E.g. if     *      the number is 5 but the row already has a 5, the cell will     *      not be set and false is returned.     * @param loc  the location of the target cell.     *             Values must be in the range [0, 80].     * @param num  the number to set in the cell.     *             Values must be in the range [1, 9].     * @return     true if the set was successful.     */    public boolean set(int loc, int num) {        // Compute row and column        int r = loc/9;        int c = loc%9;        int blockLoc = (r/3)*3+c/3;        boolean canSet = cells[loc] == 0            && (colsSet[c] & (1<<num)) == 0            && (rowsSet[r] & (1<<num)) == 0            && (subgridSet[blockLoc] & (1<<num)) == 0;        if (!canSet) {            return false;        }        cells[loc] = num;        colsSet[c] |= (1<<num);        rowsSet[r] |= (1<<num);        subgridSet[blockLoc] |= (1<<num);        return true;    }    /*     * Removes the number in a cell.     * @param loc  the location of the target cell.     *             Values must be in the range [0, 80].     */    public void clear(int loc) {        // Compute row and column        int r = loc/9;        int c = loc%9;        int blockLoc = (r/3)*3+c/3;        int num = cells[loc];        cells[loc] = 0;        colsSet[c] ^= (1<<num);        rowsSet[r] ^= (1<<num);        subgridSet[blockLoc] ^= (1<<num);    }    /**     * Returns a copy of this grid. Any modifications to the returned     * grid will not affect this grid.     *     * @return a non-null deep copy of this grid.     */    public Grid clone() {        Grid grid = new Grid();        grid.cells = cells.clone();        grid.colsSet = colsSet.clone();        grid.rowsSet = rowsSet.clone();        grid.subgridSet = subgridSet.clone();        return grid;    }    /**     * Returns a string representing the current contents of the grid.     * Used for debugging purposes.     *     * @return a non-null string representing the current contents of the grid.     */    public String toString() {        StringBuffer buf = new StringBuffer();        for (int r=0; r<9; r++) {            if (r%3 == 0) {                buf.append("-------------------------\n");            }            for (int c=0; c<9; c++) {                if (c%3 == 0) {                    buf.append("| ");                }                int num = cells[r*9+c];                if (num == 0) {                    buf.append(". ");                } else {                    buf.append(num+" ");                }            }            buf.append("|\n");        }        buf.append("-------------------------");        return buf.toString();    }}


自己建立个文件自己定义好路径

贴上你要解的数独格式、(格式应该有很多种、我只知道2种)

先贴出来几个


1、

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


2、

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




使用方法很简单、首先要建立好一个txt文件 里面放入上面的格式、

然后就是执行SudokuSolver 的java  application 的main方法、




原创粉丝点击