实现数独小例子

 

package shudutianshu;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;


public class shudu{


  // 随机数,返回1-9的随机数
  public static Integer getRandom() {
   return (int) (Math.random() * 9) + 1;
  }

  // 找到一个可填充的数;
  public static int getNumber(int[][] array, int[] pos) {
   
   List<Integer> list = new ArrayList<Integer>(9);// 如果1-9全不合要求,表示写入失败;

   int n = 0;
   do{
    n = getRandom();

    if (list.size() == 9)
     throw new RuntimeException();// 失败;
    if (!list.contains(n))
     list.add(n);
   }while (!(checkRow(array, pos, n) && checkCol(array, pos, n) && checkArea(
     array, pos, n)));

   return n;
  }

  // 检查行,有重复的,返回false
  public static boolean checkRow(int[][] array, int[] pos, int number) {
   int row = pos[0];
   for (int i = 0; i < pos[1]; i++) {
    if (i != pos[1] && number == array[row][i]) {
     return false;
    }
   }

   return true;
  }

  // 检查列,有重复的,返回false
  public static boolean checkCol(int[][] array, int[] pos, int number) {
   int col = pos[1];
   for (int i = 0; i < pos[0]; i++) {
    if (i != pos[0] && number == array[i][col])
     return false;
   }
   return true;
  }

  // 检查所在的小区域,有重复的,返回false
  public static boolean checkArea(int[][] array, int[] pos, int number) {
   int row = pos[0] / 3 * 3;// 所在区域左上角行坐标
   int col = pos[1] / 3 * 3;// 所在区域左上角列坐标
   for (int i = row; i < row + 3; i++)
    for (int j = col; j < col + 3; j++) {
     if (!(pos[0] == i && pos[1] == j) && (array[i][j] == number))// 检查时不包含自身位置
      return false;
    }
   return true;
  }

  // 产生一个数独;
  public static int[][] createSudoku() {

   boolean flag = true;
   int[][] array = null;

   int count = 0;// 一共要写多少次才能写成功;

   while (flag) {
    try {
     count++;
     array = new int[9][9];
     for (int i = 0; i < 9; i++) {
      for (int j = 0; j < 9; j++) {
       int[] pos = { i, j };
       array[i][j] = getNumber(array, pos);
      }
     }
     flag = false;// 填写完成时,终止while循环;
    } catch (RuntimeException e) {
    }
   }
   System.out.println("total try : " + count);
   return array;
  }

  @Test
  public void testNumberFactory() {
   for (int i = 0; i < 1000; i++) {
    int n = getRandom();
    if (n < 1 || n > 9)
     System.out.println(n);
   }
  }

  @Test
  public void test() {
   int[][] array = new int[9][9];
   long time1 = System.currentTimeMillis();
   array = createSudoku();
   System.out.println("total time: "
     + (System.currentTimeMillis() - time1));
   for (int i = 0; i < 9; i++) {
    for (int j = 0; j < 9; j++) {
     System.out.print(array[i][j] + " ");
    }
    System.out.println();
   }
  }
  
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值