Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 289|回复: 0

[算法学习]一个数独算法源代码(未用递归)

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-5 00:02:37 | 显示全部楼层 |阅读模式
    如果你不了解数独问题,请看这里。

    /**
      * 数独程序
      */
    public class ShuDu {
           /**存储数字的数组*/
           static int[][] n = new int[9][9];
           /**生成随机数字的源数组,随机数字从该数组中产生*/
           static int[] num = {1,2,3,4,5,6,7,8,9};
           public static void main(String[] args) {
                  //生成数字
                 for(int i = 0;i < 9;i++){
                          //尝试填充的数字次数
                          int time = 0;
                         //填充数字
                          for(int j = 0;j < 9;j++){
                                 //产生数字
                                 n[j] = generateNum(i,j,time);   
                                //如果返回值为0,则代表卡住,退回处理
                                //退回处理的原则是:如果不是第一列,则先倒退到前一列,
                                // 否则倒退到前一行的最后一列
                                if(n[j] == 0){
                                        //不是第一列,则倒退一列
                                        if(j > 0){
                                                    j-=2;
                                                    continue;
                                       }else{//是第一列,则倒退到上一行的最后一列
                                                   i--;
                                                   j = 8;
                                                   continue;
                                       }
                                 }
                                //填充成功
                                 if(isCorret(i,j)){
                                         //初始化time,为下一次填充做准备
                                       time = 0;
                                 }else{ //继续填充
                                      //次数增加1
                                      time++;
                                     //继续填充当前格
                                      j--;
                                }   
                         }             }
                
      
      
              //输出结果
                 for(int i = 0;i < 9;i++){
                            for(int j = 0;j < 9;j++){
                                       System.out.print(n[j] + "  ");
                            }
                            System.out.println();
                  }
           }   
      
            /**
             * 是否满足行、列和3X3区域不重复的要求
             * @param row 行号
             * @param col 列号
             * @return true代表符合要求
            */
            public static boolean isCorret(int row,int col){
                   return (checkRow(row) & checkLine(col) & checkNine(row,col));
            }
       
            /**
             * 检查行是否符合要求
             * @param row 检查的行号
             * @return true代表符合要求
             */
            public static boolean checkRow(int row){  
                    for(int j = 0;j < 8;j++){
                           if(n[row][j] == 0){
                                    continue;
                           }
                          for(int k =j + 1;k< 9;k++){
                                   if(n[row][j] == n[row][k]){
                                            return false;
                                   }
                          }
                     }
                    return true;
            }
       
           /**
            * 检查列是否符合要求
            * @param col 检查的列号
            * @return true代表符合要求
            */
           public static boolean checkLine(int col){
                  for(int j = 0;j < 8;j++){
                         if(n[j][col] == 0){
                                 continue;
                         }
                         for(int k =j + 1;k< 9;k++){
                                 if(n[j][col] == n[k][col]){
                                          return false;
                                 }
                         }
                 }
                return true;
            }
       
            /**
            * 检查3X3区域是否符合要求
            * @param row 检查的行号
            * @param col 检查的列号
            * @return true代表符合要求
            */
            public static boolean checkNine(int row,int col){
                    //获得左上角的坐标
                    int j = row / 3 * 3;
                    int k = col /3 * 3;
                    //循环比较
                    for(int i = 0;i < 8;i++){
                              if(n[j + i/3][k + i % 3] == 0){
                                          continue;
                              }
                             for(int m = i+ 1;m < 9;m++){
                                         if(n[j + i/3][k + i % 3] == n[j + m/3][k + m % 3]){
                                                      return false;
                                         }
                              }
                      }
                      return true;
             }
       
           /**
            * 产生1-9之间的随机数字
            * 规则:生成的随机数字放置在数组8-time下标的位置,随着time的增加,
            * 已经尝试过的数字将不会在取到
            * 说明:即第一次次是从所有数字中随机,第二次时从前八个数字中随机,依次类推,
            *       这样既保证随机,也不会再重复取已经不符合要求的数字,提高程序的效率
            * 这个规则是本算法的核心
            * @param row 需要填充的数字所在的行
            * @param col 需要填充的数字所在的列
            * @param time 填充的次数,0代表第一次填充
            * @return
            */
            public static int generateNum(int row,int col,int time){
                    //第一次尝试时,初始化随机数字源数组
                    if(time == 0){
                          for(int i = 0;i < 9;i++){
                                  num = i + 1;
                          }
                    }
                    //第10次填充,表明该位置已经卡住,则返回0,由主程序处理退回
                    if(time == 9){
                             return 0;
                    }  
                    //不是第一次填充
                    //生成随机数字,该数字是数组的下标,取数组num中该下标对应的数字为随机数字
                   int ranNum = (int)(Math.random() * (9 - time));
                   //把数字放置在数组倒数第time个位置,
                   int temp = num[8 - ranNum];
                   num[8 - ranNum] = num[ranNum];
                   num[ranNum] = temp;
                  //返回数字
                  return num[8 - ranNum];  
            }
    }

    运行三次的结果:
    C:        est>java ShuDu
    9 2 1 4 8 3 6 5 7
    3 5 6 1 7 9 2 4 8
    8 4 7 6 5 2 1 9 3
    5 7 8 2 3 1 9 6 4
    4 9 3 5 6 8 7 2 1
    6 1 2 9 4 7 8 3 5
    1 3 5 7 9 6 4 8 2
    7 6 4 8 2 5 3 1 9
    2 8 9 3 1 4 5 7 6 C:        est>java ShuDu
    3 6 2 5 4 8 1 7 9
    9 5 7 3 6 1 2 4 8
    1 8 4 7 2 9 6 3 5
    7 9 8 6 3 5 4 1 2
    2 4 6 8 1 7 5 9 3
    5 3 1 4 9 2 8 6 7
    6 2 9 1 5 3 7 8 4
    8 1 5 9 7 4 3 2 6
    4 7 3 2 8 6 9 5 1 C:        est>java ShuDu
    6 5 4 7 8 2 3 9 1
    3 7 1 5 6 9 8 4 2
    8 9 2 3 1 4 6 7 5
    7 8 9 2 5 1 4 3 6
    5 4 6 8 3 7 1 2 9
    1 2 3 4 9 6 7 5 8
    4 1 8 9 2 3 5 6 7
    2 6 7 1 4 5 9 8 3
    9 3 5 6 7 8 2 1 4  
       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/5/000236734.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 13:41 , Processed in 0.306555 second(s), 36 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表