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 |
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操作等。最大体会就是和同学交流更容易懂,百度有时候讲的太多又看不懂(我太难了),整个过程下来,总结就是要多动手,多找资料,不懂去问。