首页 > 其他 > 详细

高级软件工程第二次作业:随机生成N个不重复的已解答完毕的数独棋盘

时间:2018-09-30 00:48:21      阅读:266      评论:0      收藏:0      [点我收藏+]
#include <stdio.h> 
#include "SuduCheck.h"
int SuduCheck(int temp[9][9],int i,int j,int k)  //判断是否可以将第i行、第j列的数设为k
{
     int m,n;
     //判断行
     for(n=0;n<9;n++)
     {
        if(temp[i][n]==k)
            return 0;               
     }
     //判断列
     for(m=0;m<9;m++)
     {
        if(temp[m][j]==k)
            return 0;
     }
    //判断所在小九宫格
    int t1=(i/3)*3,t2=(j/3)*3;
    for(m=t1;m<t1+3;m++)
    {
        for(n=t2;n<t2+3;n++)
        {
             if(temp[m][n]==k)
                 return 0;
         }
     }
     //可行,返回true
     return 1;
}
SuduCheck()函数可以对数据进行判断,判断是否符合数独数列的规则。判断同一行有无从复数字,判断同一列有无从复数字,判断同一宫有无重复数字。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "SuduInput.h"
#include "SuduCheck.h"
#include "SuduGain.h"
void cleanup(int temp[9][9])
{
    int i,j;
    for(i=0;i<9;i++)
    {
        for(j=0;j<9;j++)
        {
            temp[i][j]=0;
        }
    }
}

int SuduGain(int temp[9][9])
{
    int i,j,m,n,random=1;  //初始值第一个随机数是我学号最后一位,201810775001 
    //srand((unsigned)time(NULL));  //随机数据初始化
    for(i=0;i<9;i++)   //循环每一行 
    {
        for(j=0;j<9;j++)  //循环每一列 
        {
            m=0;
            while(SuduCheck(temp,i,j,random)==0)  //判断此随机数是否能够使用,如果能够使用跳出循环,否则继续循环 
            {
                random=rand()%9+1;  //生成一个0-9的随机数
                m++;
                if(m>100)  //如果同一个位置循环100次失败,判断此数独行失败,返回从新开始 
                {
                    return 0;//此数独数列失败,从新开始        
                }
            }
            temp[i][j]=random;//此数已经通过检查,可以放入数组 
            //SuduInput(temp);
            //printf("m=%d  n=%d\trandom=%d\n",m,n,random);
            //getch();
        }    
    }
    return 1;  //数独列表生成成功 
} 
SuduGain()函数形成数独数列,随机生成0-9任意数据,如果符合数独数列要求就加入数独数列之中。如果随机的数据100次都不符合要求,则判断此数独数列失败,否则就能够成功。
#include <stdio.h>
#include <stdlib.h> 
#include "SuduInput.h"
void SuduInput(int temp[9][9])
{
    int i,j;
    FILE *fp;
     //数独输出到屏幕
    for(i=0;i<9;i++)  
    {
        for(j=0;j<9;j++)
        {
            printf("%d",temp[i][j]);    
        }
        printf("\n");    
    }
    printf("\n");
     //数独输出到文档 
    if((fp = fopen("sudotiku.txt", "a+")) == NULL)
    {
        printf("Can,t opent file!");
        exit(1);
    }
    for(i=0;i<9;i++)  
    {
        for(j=0;j<9;j++)
        {
            fprintf(fp,"%d ",temp[i][j]);    
        }
        fprintf(fp,"\n");        
    }
    fprintf(fp,"\n");  
    fclose(fp);
}
SuduInput()输出数独数列数组在屏幕上和sudotiku.txt文本当中。
#include <stdio.h>
#include <stdlib.h>
#include "SuduInput.h"
#include "SuduCheck.h"
#include "SuduGain.h"
int sudo[9][9]={0};
int main(int argc, char *argv[]) 
{
    int i,n;
    n=atof(argv[2]);  //输入需要数独数据个数
    for(i=0;i<n;i++)  //循环获得数独 
    {    
        do 
        {
            cleanup(sudo);  //清理数组 
        }while(SuduGain(sudo)==0);  //如果数独生成失败,返回结果为0,则清空sudo数组,继续再试直到成功 
        SuduInput(sudo); 
    }
    return 0;
}

main()函数中获得需要随机的数独个数,调用SuduGain()函数生成数独数列,如果成功就进行下一次生成,直到完全题目要求。

 

分析:程序能够正确的生成多个数独数列,完整加入.h文件代码在https://git.coding.net/longjiangteng/sudoti.git中可以查看。但是代码效率很低,使用生成方法过于简单,需要计算机大量的运算尝试。随机函数rand()并不能做到真随机,多次生成的数独数列会有重复。还是具有持续改进的余地。

 

心得:使用C语言编写数独程序非常复杂,提高效率的算法我一直没有能够理解,这就是我遇到的问题。只能花费多个晚上使用了一个最笨的办法完成了作业,感到非常的惭愧。



高级软件工程第二次作业:随机生成N个不重复的已解答完毕的数独棋盘

原文:https://www.cnblogs.com/longjiangteng/p/9727250.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!