java求解数独(递归)

来源:互联网 发布:种植牙植体品牌 知乎 编辑:程序博客网 时间:2024/06/06 02:52

/**
* 先来一些测试用例
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
*


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


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


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

public class Test {    private static int count = 0;    private static int trys = 0;    private static int trys2 = 0;    private static long end;    private static boolean found = true;    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        int length = 9;        int[][] arr = new int[length][length];        for (int i = 0; i < length; i++) {            String line = scanner.nextLine();            for (int j = 0; j < line.split(" ").length; j++) {                arr[i][j] = Integer.parseInt(line.split(" ")[j]);            }        }        long start = System.nanoTime();        execute(arr, true);        System.out.println("总共有:" + count + " 种组合!尝试了:" + trys + "种组合.其中尝试" + trys2 + "种找到第一个结果!总耗时:" + (System.nanoTime() - start) / 1000000 + "ms," +                "其中第一例耗时:" + (end - start) / 1000000 + "ms");    }    /**     * h 纵     * w 横     *     * @param arr     * @return     */    public static String execute(int[][] arr, boolean first) {        int[] zero = getZero(arr);        if (zero == null) {            return print(arr);        }        Integer[] canUse = getSomething(arr, zero);        if (canUse == null || canUse.length < 1) {            return "error";        }        for (int num : canUse) {            trys++;            arr[zero[0]][zero[1]] = num;            if (first) {                System.out.println("============================>>" + Arrays.toString(canUse) + "now try to set arr[" + zero[0] + "][" + zero[1] + "]=" + num);            }            String result = execute(arr, false);            if (!"error".equals(result)) {                System.out.println("===============" + (++count) + "=================" + "\r\n" + result);                if (found) {                    end = System.nanoTime();                    trys2 = trys;                }                found = false;            }            arr[zero[0]][zero[1]] = 0;//还原        }        return "error";    }    private static int[] getZero(int[][] arr) {        for (int h = 0; h < arr.length; h++) {            for (int w = 0; w < arr[h].length; w++) {                if (0 == arr[h][w]) {                    return new int[]{h, w};                }            }        }        return null;    }    private static String print(int[][] arr) {        StringBuilder sb = new StringBuilder();        for (int h = 0; h < arr.length; h++) {            for (int w = 0; w < arr[h].length - 1; w++) {                sb.append(arr[h][w]).append(" ");            }            sb.append(arr[h][arr[h].length - 1]).append("\r\n");        }        return sb.toString().substring(0, sb.length() - 2);    }    private static Integer[] getSomething(int[][] arr, int[] zero) {        int[] all = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};        int[] temp = getBlock(arr, zero[0], zero[1]);        for (int i = 0; i < arr.length; i++) {            all[arr[zero[0]][i]] = 0;            all[arr[i][zero[1]]] = 0;            all[temp[i]] = 0;        }        List<Integer> list = new ArrayList<>();        for (int i = 0; i < all.length; i++) {            if (0 != all[i]) {                list.add(all[i]);            }        }        Object[] objects = list.toArray();        Integer[] ret = new Integer[objects.length];        return list.toArray(ret);    }    private static int[] getBlock(int[][] arr, int h, int w) {        int blockId = getBlockId(h, w);        h = (int) Math.ceil(blockId / 3.0);//第几行开始        w = blockId % 3 == 0 ? 3 : blockId % 3;//第几列开始        int[] temp = new int[9];        for (int j = 0; j < 3; j++) {            for (int k = 0; k < 3; k++) {                temp[j * 3 + k] = arr[(h - 1) * 3 + j][(w - 1) * 3 + k];            }        }        return temp;    }    private static int getBlockId(int h, int w) {        return ((h < 3 ? 1 : h < 6 ? 2 : 3) - 1) * 3 + (w < 3 ? 1 : w < 6 ? 2 : 3);    }}

看到这个是华为的面试题,觉得有点意思,就花了点时间写了(最后花了大概4个小时T_T惭愧T_T)。大学刚毕业,做个纪念,以后越来越好!!!

0 0
原创粉丝点击