数独算法——生得数独表

package Demo01;

import java.util.Random;

public class ShuDu2 {
	/** 存储数字的数组 */
	private static int[][] outcome = new int[9][9];// 公共数据

	public static void main(String[] args) throws InterruptedException {
		int success = getShuDuArray(1, getArr(), 0);
		if (success == 1) {
			for (int i = 0; i < 9; i++) {
				for (int j = 0; j < 9; j++) {
					System.out.print(outcome[i][j] + " ");
				}
				System.out.println();
				// System.out.println("第"+i+"行运行正常");
				// Thread.sleep(1000);
			}
			System.out.println("81个数字符合数独要求,本次运行正常");
		}
	}

	/**
	 * 
	 * @param count:当前棋盘位置数,总共81个格子,从左往右,从上往下数
	 * @param nums:每次给定一个随机生成数的数组。
	 * @param time:每个空格更新数的次数。
	 * @return:当前格子是否成功
	 */
	public static int getShuDuArray(int count, int nums[], int time) {
		// 通过count计算出row and col
		int row = getRow(count);
		int col = getCol(count);
		if (count == 82) {
			return 1;// 表示成功啦!!!
		}
		while (true)// 等于9表示第10次取数。
		{
			outcome[row][col] = generateNum(time, nums);// 开始填充该空格数字
			// 如何所有数用完了,向下递归,接力赛
			if (outcome[row][col] == 0) {
				break;
			}
			if (isCorret(row, col)) {// 此时填充成功。向下递归。
				int k = getShuDuArray(count + 1, getArr(), 0);
				if (k == -1) {// 表示下层挂了,下层回溯,本层换数。
					time++;
				} else {// 肯定会返回1的,表示成功完成任务了。81层全部各司其职,尽责尽职。
					return 1;// 成功
				}
			} else {// 本层与前面的数字矛盾
				time++;
			}

		}
		return -1;// 本层所有数要完了。卡住,向上层汇报
	}

	public static int[] getArr() {
		int[] arr = new int[9];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = i + 1;
		}
		return arr;
	}

	public static int getRow(int count) {
		int row;
		if (count % 9 == 0) {
			row = (count / 9) - 1;
		} else {
			row = (count / 9);
		}
		return row;
	}

	public static int getCol(int count) {
		int col;
		if (count % 9 == 0) {
			col = (count - 1) % 9;
		} else {
			col = count % 9 - 1;
		}
		return col;
	}

	private static Random r = new Random();

	private static int generateNum(int time, int[] arr) {

		// 第10次填充,表明该位置已经卡住,则返回0,由主程序处理退回
		if (time == 9) {
			return 0;
		}
		// 不是第一次填充
		// 生成随机数字,该数字是数组的下标,取数组num中该下标对应的数字为随机数字
		// int ranNum = (int) (Math.random() * (9 - time));//j2se
		int ranNum = r.nextInt(9 - time);// j2me
		// 把数字放置在数组倒数第time个位置,
		int temp = arr[8 - time];
		arr[8 - time] = arr[ranNum];
		arr[ranNum] = temp;
		// 返回数字
		return arr[8 - time];
	}

	private static boolean checkNine(int row, int col) {
		// 获得左上角的坐标
		int j = row / 3 * 3;
		int k = col / 3 * 3;
		int l = j;// 遍历行
		int m = k;// 遍历列
		// 遍历所有目标数outcome[row][col]之前的所有数是否和该目标数重复
		while (l != row || m != col) {// 进行遍历
			if (outcome[l][m] == outcome[row][col]) {
				return false;
			} else {
				m++;// 向前进
				if ((m / 3 * 3) > k) {// 超出范围
					m = k;
					l++;
				}
			}
		}
		return true;
	}

	/**
	 * 检查列是否符合要求
	 * 
	 * @param col
	 *            检查的列号
	 * @return true代表符合要求
	 */
	private static boolean checkLine(int col) {
		for (int j = 0; j < 8; j++) {
			if (outcome[j][col] == 0) {
				continue;
			}
			for (int k = j + 1; k < 9; k++) {
				if (outcome[j][col] == outcome[k][col]) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 检查行是否符合要求
	 * 
	 * @param row
	 *            检查的行号
	 * @return true代表符合要求
	 */
	private static boolean checkRow(int row) {
		for (int j = 0; j < 8; j++) {
			if (outcome[row][j] == 0) {
				continue;
			}
			for (int k = j + 1; k < 9; k++) {
				if (outcome[row][j] == outcome[row][k]) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 是否满足行、列和3X3区域不重复的要求
	 * 
	 * @param row
	 *            行号
	 * @param col
	 *            列号
	 * @return true代表符合要求
	 */
	private static boolean isCorret(int row, int col) {
		return (checkRow(row) & checkLine(col) & checkNine(row, col));
	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值