2019软工第三次作业
软工第三次作业
github项目地址
https://github.com/CDCDA/001.git
PSP表格
|||||||||
|:--|:--|:--|:--|
|PSP2.1|Personal Software Process Stages|预估耗时(分钟)|实际耗时(分钟)
|Planning|计划| 0.5h | 1h
|Estimate|估计这个任务需要多少时间| 15h |20.8h
|Development |开发 |3h|4h
|Analysis| 需求分析(包括学习新技术) |2h |4h
|Design Spec| 生成设计文档 |0.5h|0.4h
|Design Review| 设计复审 |0.5h |0.2
|Coding Standard|代码规范 (为目前的开发制定合适的规范) |0.1h|0.1h
|Design|具体设计|0.5h |0.6h
|Coding |具体编码 | 3h|3.5h
|Code Review|代码复审|1h| 2h
|Test| 测试(自我测试,修改代码,提交修改)|2h|3h
|Reporting |报告 |0.1h|0.2h
|Test Repor |测试报告 ** |0.1h|0.1h**
|Size Measurement |计算工作量 |1.2h|1.5h
|Postmortem & Process Improvement Plan |事后总结, 并提出过程改进计划|0.5h| 0.2h
|合计||15h|20.8h|
设计思路
看到题目第一反应就是先把代码写了,其他的附加要求我都先扔在了一边。
数独的要求是每一行,每一列和每一宫的合法不重复,于是我写了一个函数来分析数独数字的合理性,由于数独的格数种类不多,我选择直接穷举。另一点就每一个数字都需要验证,我想到了以前用过的回溯法,利用深度搜索寻找数独的解。
求解函数如下
bool rightSudoku(int num,int m)//判断数字
{
int a,b,i,j,row,col;
row=num/m;col=num%m;
for(i=0;i<m;i++)
{
if(Sudoku[row][i]==Sudoku[row][col]&&i!=col)
return false;
}//每行遍历
for(i=0;i<m;i++)
{
if(Sudoku[i][col]==Sudoku[row][col]&&i!=row)
return false;
}//每列遍历
int x,y;
if(m==5||m==7||m==3)
return true;
else
{
if(m==9||m==4)
{
a=sqrt(m);
b=sqrt(m);
}
if(m==6)
{
a=2;b=3;
}
if(m==8)
{
a=2;b=4;
}
x=row/a*a;
y=col/b*b;
for(i=x;i<x+a;i++)
{
for(j=y;j<y+a;j++)
{
if(Sudoku[row][col]==Sudoku[i][j]&&i!=row&&j!=col)
return false;
}
} //每宫遍历
}
return true;
}
void back(int num,int m)
{
if(num==m*m)
save(m);
int i;
int row=num/m;
int col=num%m;//得到坐标
if(Sudoku[row][col]==0)
{
for(i=1;i<=m;i++)
{
Sudoku[row][col]=i;
if(rightSudoku(num,m)==1)
back(num+1,m);//数字符合要求判断下一位
}
Sudoku[row][col]=0;//不符合要求则回溯
}
else back(num+1,m);
}
验证代码后才发现这些附加要求才是最麻烦的,以前我并没有接触过这类操作,只能求助于百度学习主函数引入参数和文件流,但是当时两眼一抹黑着实花费很长的时间。
按照作业要求,argv[2][4][6][8]即是我们想要的参数,再使用文件流输入输出即可。
int n, m, i, j;
char c;
int a[10][10];
ifstream infile;
ofstream outfile;
for(i=0;i<8;i++)
{
if(argv[i][1]=='m')
m = atoi(argv[i+1]);
if(argv[i][1]=='n')
n = atoi(argv[i+1]);
if(argv[i][1]=='i')
{
infile.open(argv[i+1]);
if (!infile.is_open())
cout << "打开输入文件错误" << endl;
}
if(aggv[i][1]=='o')
{
outfile.open(argv[i+1]);
if (!infile.is_open())
cout << "打开输出文件错误" << endl;
else cout<<"error"<<endl;
}
}
for (n; n > 0; n--)
{
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
{
infile >> c;
a[i][j] = c - 48;
}
}
input(m, a);
back(0, m);
}
infile.close();
结果
检错
性能分析
时间不太够,但目前来看对我而言收获还是很大的。