第二次作业------个人项目战:数独

代码相关

执行力 、 泛泛而谈 的理解

  • 执行力,我的理解是这样的。第一步,确定一个目标;第二步,计划整个好行动;第三步,执行整个计划;第四步,总结和回顾。执行力就贯穿在这四步,如果有人一件事情按着这四步来,每一步都有实际的行动,并出色的完成。我觉得这个人就是有执行力的。当然很多人做不到的,在做一件事的过程中,懈怠或放弃,最终导致目标没有达成。

  • 泛泛而谈,我的理解是。没有明确的观点,没有严谨的逻辑,没有实际案例。

项目需求

  • 随机生成N个已解答的数独终盘。

  • 输入: 数独棋盘题目个数N(0< N<=1000000)

  • 输出: 随机生成N个不重复的数独终盘,并输出到sudoku.txt中

解题思路

随机生成第一行的1~9排列,第2到9行通过回溯法来产生。
对于第2到9行的每一个空格,要从1到9逐个尝试放入,
看同一列、同一行、同一个3×3的小方阵中是否出现过相同的数字,
若没有就尝试放入,然后递归地搜索下一个位置的数字,
若1到9都不行就返回上一个位置尝试下一个数字,直到找到一组解就返回。

遇到的困难及解决方法

  • 在做数独的过程中遇到了挺多困难的,比如拿到题目没有思路,找了很多的博客和资料,在编程之美里面找到了很多思路,像回溯法,变换法之类的,还有很多没深究没看懂的解法。在看到回溯法的思路的时候,一直没想明白,尝试一个数的填充,如果违反了三个判断条件,返回后,用下一个数进行尝试,发现走到了死胡同了,这时候要如何回溯,又回溯到哪一步呢。
  • 看了很多代码和博客,才想起来递归。

设计实现

  • 在main函数中进行命令行参数接收检错、首个数字的生成和输出结果到sudoku.txt。
  • 在set_zero函数中将9x9的g格子进行初始化,并完成第一行的数字1~9随机填充。
  • 在set_number函数中进行经典回溯法填充余下的2~9行数字。

代码说明

  • 健壮性

//参数个数检测 
for(int i=0;i<argc;i++)  {
    count_argv = i;
}
if( count_argv != 2 ) {
	cout<<"error: 参数个数要求2个,正确例子“sudoku.exe -c 2”"<<endl; 
	return 0;
}

//“-c”参数检测 
s = argv[1];
if( s.compare("-c") != 0) {
	cout<<"error: 参数错误1,正确例子“sudoku.exe -c 2”"<<endl; 
	return 0;
}

//count参数检测 
istringstream stream1;
  string string1 = argv[2];
  stream1.str(string1);
  stream1 >> count;
if ( count == 0 ) {
	cout<<"error: 参数错误2,正确例子“sudoku.exe -c 2”"<<endl; 
	return 0;
}
  • 初始化
void start_work(int res)   
{   
    //产生random_shuffle的随机数种子
	int temp = rand();
    srand ( unsigned ( time (NULL) + temp ) ); 
	
	//所有格子赋0值  
    for( int i = 1  ; i <= 9 ; ++i ) { 
        for( int j = 1 ; j <= 9 ; ++j )  {
            set_zero[i][j] = 0 ;  
        } 
    } 
    
    //第一行赋值1~9 
    for( int i = 1 ; i <= 9 ; ++i )   
        set_zero[1][i] = i ;   
    
    //将第一行数值随机排列
    random_shuffle( &( set_zero[1][1]) , &( set_zero[1][10])  ) ;   
    
    //换置学号得到的第一个数字 
    temp = set_zero[1][1];
    for( int i = 1 ; i <= 9 ; ++ i ){
    	if( set_zero[1][i] == res ){
    		set_zero[1][i] = temp;
    	}
    }
    set_zero[1][1] = res;
    
    //从第二行开始填充数值 
    set_number( 2 , 1 ) ;   
}  
  • 填充(三个判断)
// is_do 变量用于记录数字k能否放在 ( i , j ) 处  
bool is_do = true;       
// 检查同一列是否出现过数字k           
for( int m = 1 ; m < i ; ++m )   
    if( set_zero[m][j] == k ) 
    {  
        is_do = false ;  
        break ;  
    }  
// 检查同一行是否出现过数字k  
if ( is_do )   
    for( int n = 1 ; n < j ; ++n )   
        if( set_zero[i][n] == k ) 
        {  
            is_do = false ;  
            break;   
        }  
// 检查在3x3的小方格中是否出现了同一个数字 
if( is_do )   
{  
    int up1 = ( i/3 ) * 3 + 3 ; 
    int up2 = ( j/3 ) *3 + 3;   
    if( i % 3 == 0 )    
        up1 = i ;   
    if( j % 3 == 0 )   
        up2 = j ;  
    for( int p = up1-2 ; p <= up1 ; ++p  )  
    {  
        if( is_do == false )   
            break ;  
        for( int q = up2-2 ; q <= up2 ; ++q )   
            if( set_zero[p][q] == k )   
            {  
                is_do = false ;  
                break ;  
            }  
    }  
}  

测试运行


关于执行力与泛泛而谈

PSP

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60 120
· Estimate · 估计这个任务需要多少时间 1200 4200
Development 开发
· Analysis · 需求分析 (包括学习新技术) 360 1200
· Design Spec · 生成设计文档 60 60
· Design Review · 设计复审 (和同事审核设计文档) 0 0
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 60 60
· Design 具体设计 120 600
· Coding 具体编码 120 1200
· Code Review 代码复审 0 0
· Test · 测试(自我测试,修改代码,提交修改) 0 0
Reporting 报告 60 60
· Test Report 测试报告 0 0
· Size Measurement · 计算工作量 60 60
· Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 60
合计 ** ** 1200 3420
原文地址:https://www.cnblogs.com/bsyt/p/7502789.html