软件工程实践2019第三次作业

Github地址:https://github.com/1hurricane/021700913

psp

PSP2.1 Personal Software Process Stages 预估耗时(小时) 实际耗时(小时)
Planning 计划 1 1
Estimate 估计这个任务需要多少时间 22 29
Development 开发 2 2
Analysis 需求分析 (包括学习新技术) 2 3
Design Spec 生成设计文档 1 1
Design Review 设计复审 1 1
Coding Standard 代码规范 (为目前的开发制定合适的规范) 2 1
Design 具体设计 2 2
Coding 具体编码 3 5
Code Review 代码复审 1 3
Test 测试(自我测试,修改代码,提交修改) 2 5
Reporting 报告 2 2
Test Repor 测试报告 1 1
Size Measurement 计算工作量 1 1
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 1 1
合计 22 29
#解题步骤 总共分成三部分,第一个就是解数独核心算法:回溯法,起到遍历的作用;第二个就是回溯算法里面包含一个函数用来判断数字合法性;第三个就是文件读写操作。 ##1.我要解数独 看到题目核心就是解数独嘛,我一看这感觉跟之前做走迷宫的题差不多,就遍历嘛,一直试,不行回头,所以核心算法的话当时就想到回溯法。 ###核心算法 ``` void SolveSudoku(int i, int j)//从a【0】【0】开始一个一个试 { if (i >= m) { for(int j1=0;j1=m的时候说明,一计算完数独。打印即可。

if (j >= m)
{
SolveSudoku(i + 1, 0);
}//j>=m的时候说明当前的行已经匹配完成。

if (Sudoku[i][j] == 0)
{
for (int num = 1; num <= m; num++)
{
if (isValid(i, j, num))//判断num合法性
{
Sudoku[i][j] = num;//回溯算法一定要保留现场和恢复现场。这样下次计算不会出现问题。
SolveSudoku(i, j + 1);
Sudoku[i][j] = 0; //【i】【j+1】不满足时退回来,说明此时【i】【j】不满足,置零重新开始
}
}
}
else if(i<m&&j<m)//判断是否到最后一个了
SolveSudoku(i, j + 1);

}

##2.文件读写操作和命令行参数
其实以前没怎么用过文件读写操作,基本都是编译运行就没了(我真是太菜了),然后就一脸懵逼,开始百度,问同学,怎么导入文件,写入文件,然后就是多个盘怎么读入,想不到什么好的方法(主要还是读取操作不熟,不知道有什么方便的操作),我就一次性全读出来,然后根据参数n来分别对几个盘操作。代码中m,n是全局变量,这个开始没设置好,导致不能传参数给SolveSukoku函数,调试了很久。

int main(int argc,char argv[])
{
m=
argv[2]-48;
n=*argv[4]-48;
char a[1000],p;

ifstream infile;
infile.open(argv[6]);
outfile.open(argv[8]);
int i=0;
while(!infile.eof())
{
infile.get(p) ;
if('0'<=p&&p<='9')
{
a[i]=p;
i++;
}
}
infile.close();//读取文件结束

int flag,now;
flag=1;
now=0;//数组a下标
while(flag<=n)//m阶数独个数
{
int j1,j2;
for(j1=0;j1<m;j1++)
for(j2=0;j2<m;j2++)
{
Sudoku[j1][j2]=(int)a[now]-48;
now++;
}
outfile<<flag<<":"<<endl;

        SolveSudoku(0,0);
        flag++;
        
        
}
   
outfile.close() ; 

return 0;
}

##3.3阶到9阶
 一开始就是用回溯写了九宫格,然后拓展到其他宫格,只是判断所填数字合法性上面加了判断就没什么差别。

bool isValid(int row, int col, int val)//检查填入数字的合法性
{
if (row < 0 || row >= m || col < 0 || col >= m)
{
return false;
}

if (Sudoku[row][col] != 0)
{
return false;
}

for (int i = 0; i < m; i++)
{
if (Sudoku[row][i] == val)
{
return false;
}
}

for (int i = 0; i < m; i++)
{
if (Sudoku[i][col] == val)
{
return false;
}
}

if(m==4)
{
int row1 = row / 2;
int col1 = col / 2;
int rowstart = row1 * 2;
int colstart = col1 * 2;
for (int i = rowstart; i < rowstart + 2; i++)
{
for (int j = colstart; j < colstart + 2; j++)
{
if (Sudoku[i][j] == val)
{
return false;
}
}
}
}

if(m==6)
{
int row1 = row / 2;
int col1 = col / 3;
int rowstart = row1 * 2;
int colstart = col1 * 3;
for (int i = rowstart; i < rowstart + 2; i++)
{
for (int j = colstart; j < colstart + 3; j++)
{
if (Sudoku[i][j] == val)
{
return false;
}
}
}
}

if(m==8)
{
int row1 = row / 4;
int col1 = col / 2;
int rowstart = row1 * 4;
int colstart = col1 * 2;
for (int i = rowstart; i < rowstart + 4; i++)
{
for (int j = colstart; j < colstart + 2; j++)
{
if (Sudoku[i][j] == val)
{
return false;
}
}
}
}

if(m==9)
{

int row1 = row / 3;
int col1 = col / 3;
int rowstart = row1 * 3;
int colstart = col1 * 3;
for (int i = rowstart; i < rowstart + 3; i++)
{
for (int j = colstart; j < colstart + 3; j++)
{
if (Sudoku[i][j] == val)
{
return false;
}
}
}
}

return true;

}

#性能分析
![](https://img2018.cnblogs.com/blog/1797579/201909/1797579-20190925172602399-919655617.png)

![](https://img2018.cnblogs.com/blog/1797579/201909/1797579-20190925172715970-1661711036.png)

#测试结果
因为刚开始没有文件读写操作,是直接定义的数独,后来用文件读写操作,变量m忘记设成全局变量,导致SolveSudoku函数出错(用到参数m),然后我以为是自己文件读写操作有错,就开始找bug,从文件输入验证输入有没有错,再验证输出有没有错(这边验证是新建程序操作的),发现并没有错,但在源程序里面就是不行,因为我就写了两个函数,所以就看函数有没有写错才发现参数传递有错(忘记保留错误截图了)。
![](https://img2018.cnblogs.com/blog/1797579/201909/1797579-20190925145009833-1465291185.png)

![](https://img2018.cnblogs.com/blog/1797579/201909/1797579-20190925145016966-925366527.png)
#心得体会
怎么说呢,解数独题目感觉不难,很快就写完了(用devc++写的),后来要调试和性能分析不得不去安装vs,安装花了很长时间,安装完还不会用,又琢磨了很久才搞完,最头大的是那个预编译头,第一次碰到,同学也不是很清楚,就又各种试,最后还是在同学帮助下才弄好的。但过程下来还是有很多收获的,会用vs(基本的操作),预编译又是啥,GitHub操作等。最大体会就是和同学交流更容易懂,百度有时候讲的太多又看不懂(我太难了),整个过程下来,总结就是要多动手,多找资料,不懂去问。
原文地址:https://www.cnblogs.com/hurricane1/p/11581445.html