软件工程实践第三次作业
GitHub地址:https://github.com/Yuqiancha919/061700232
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 120 | 120 |
Estimate | 估计这个任务需要多少时间 | 3600 | 7200 |
Development | 开发 | 60 | 60 |
Analysis | 需求分析 (包括学习新技术) | 60 | 120 |
Design Spec | 生成设计文档 | 30 | 30 |
Design Review | 设计复审 | 60 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 60 |
Design | 具体设计 | 120 | 120 |
Coding | 具体编码 | 120 | 180 |
Code Review | 代码复审 | 120 | 120 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 180 |
Reporting | 报告 | 120 | 150 |
Test Repor | 测试报告 | 30 | 60 |
Size Measurement | 计算工作量 | 30 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 120 |
合计 | 3600 | 9600 |
题目回顾
数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。!
现在我们想一步一步来,完成从三宫格到九宫格的进阶;完成三宫格和其他博客任务,就算过了初级考核,其他的算升级。具体各阶规则如下:
三宫格:盘面是33。使1-3每个数字在每一行、每一列中都只出现一次,不考虑宫;
四宫格:盘面是22四个宫,每一宫又分为22四个小格。使1-4每个数字在每一行、每一列和每一宫中都只出现一次;
五宫格:盘面是55。使1-5每个数字在每一行、每一列中都只出现一次,不考虑宫;
六宫格:盘面是23六个宫,每一宫又分为32六个小格。使1-6每个数字在每一行、每一列和每一宫中都只出现一次;
七宫格:盘面是77。使1-7每个数字在每一行、每一列中都只出现一次,不考虑宫;
八宫格:盘面是42八个宫,每一宫又分为24八个小格。使1-8每个数字在每一行、每一列和每一宫中都只出现一次;
九宫格:盘面是33九个宫,每一宫又分为3*3九个小格。使1-9每个数字在每一行、每一列和每一宫中都只出现一次;
思路
刚开始看到这道题的时候感觉很难,然后就拖延了几天。当发现时间已经过了很久了,然后我坐下来认真想了想。现在大概已经做完了,我回头去想感觉我的方法还是不太好。
我的想法很简单,就是对整个x宫格进行一个一个的检查,定义了三维数组,前两维是用来存x宫格的盘面,第三维是用来存这个格子所能填的数字。对每一个各自进行检查,检查这个格子的行和列还有小宫格有哪些数字已经出现过,将其标记。最后检查哪些格子只有一个数字没有被标记就直接将其填入这个格子。然后重复上面的操作。当格子里没有0的时候就停止,输出。
当时我实现了以后,发现了问题。对于一些刚开始填入的数据比较少的宫格,这个方法就有可能没有办法完成。后来我通过在网上的学习,学习到了递归的做法,对每个格子可能的数进行尝试,尝试失败就返回来,尝试成功就可以完成了。
代码实现
这个是实现的代码
void inti()
{
int i, j, k;
int cnt = 0;
for (i = 1; i < N; i++)
for (j = 1; j < N; j++)
{
if (sudu[i][j][0] == 0)
{
for (k = 1; k < N; k++)
{
if (sudu[i][k][0] != 0)
sudu[i][j][sudu[i][k][0]] = 0;
}
for (k = 1; k < N; k++)
{
if (sudu[k][j][0] != 0)
sudu[i][j][sudu[k][j][0]] = 0;
}
if (N == 5 || N == 7 || N == 9 || N == 10)
{
if (N == 10)
ninesudu(i, j);
if (N == 9)
eightsudu(i, j);
if (N == 7)
sixsudu(i, j);
if (N == 5)
foursudu(i, j);
}
for (k = 1; k < N; k++)
{
if (sudu[i][j][k] != 0)
cnt++;
}
if (cnt == 1)
{
for (k = 1; k < 10; k++)
{
if (sudu[i][j][k] != 0)
{
sudu[i][j][0] = k;
break;
}
}
}
}
cnt = 0;
}
}
要考虑到所有宫格
//九宫格
void ninesudu(int i, int j)
{
int m, n;
if (i <= 3)
{
if (j <= 3)
{
for (m = 1; m < 4; m++)
for (n = 1; n < 4; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 6)
{
for (m = 1; m < 4; m++)
for (n = 4; n < 7; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 9)
{
for (m = 1; m < 4; m++)
for (n = 7; n < 10; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
else if (i <= 6)
{
if (j <= 3)
{
for (m = 4; m < 7; m++)
for (n = 1; n < 4; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 6)
{
for (m = 4; m < 7; m++)
for (n = 4; n < 7; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 9)
{
for (m = 4; m < 7; m++)
for (n = 7; n < 10; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
else if (i <= 9)
{
if (j <= 3)
{
for (m = 7; m < 10; m++)
for (n = 1; n < 4; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 6)
{
for (m = 7; m < 10; m++)
for (n = 4; n < 7; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 9)
{
for (m = 7; m < 10; m++)
for (n = 7; n < 10; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
}
//八宫格
void eightsudu(int i, int j)
{
int m, n;
if (i <= 4)
{
if (j <= 2)
{
for (m = 1; m < 5; m++)
for (n = 1; n < 3; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 4)
{
for (m = 1; m < 5; m++)
for (n = 3; n < 5; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 6)
{
for (m = 1; m < 5; m++)
for (n = 5; n < 7; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 8)
{
for (m = 1; m < 5; m++)
for (n = 7; n < 9; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
else if (i <= 8)
{
if (j <= 2)
{
for (m = 5; m < 9; m++)
for (n = 1; n < 3; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 4)
{
for (m = 5; m < 9; m++)
for (n = 3; n < 5; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 6)
{
for (m = 5; m < 9; m++)
for (n = 5; n < 7; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 8)
{
for (m = 5; m < 9; m++)
for (n = 7; n < 9; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
}
//六宫格
void sixsudu(int i, int j)
{
int m, n;
if (i <= 2)
{
if (j <= 3)
{
for (m = 1; m < 3; m++)
for (n = 1; n < 4; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 6)
{
for (m = 1; m < 3; m++)
for (n = 4; n < 7; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
else if (i <= 4)
{
if (j <= 3)
{
for (m = 3; m < 5; m++)
for (n = 1; n < 4; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 6)
{
for (m = 3; m < 5; m++)
for (n = 4; n < 7; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
else if (i <= 6)
{
if (j <= 3)
{
for (m = 5; m < 7; m++)
for (n = 1; n < 4; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 6)
{
for (m = 5; m < 7; m++)
for (n = 4; n < 7; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
}
//四宫格
void foursudu(int i, int j)
{
int m, n;
if (i <= 2)
{
if (j <= 2)
{
for (m = 1; m < 3; m++)
for (n = 1; n < 3; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 4)
{
for (m = 1; m < 3; m++)
for (n = 3; n < 5; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
else if (i <= 4)
{
if (j <= 2)
{
for (m = 3; m < 5; m++)
for (n = 1; n < 3; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
else if (j <= 4)
{
for (m = 3; m < 5; m++)
for (n = 3; n < 5; n++)
{
if (sudu[m][n][0] != 0)
sudu[i][j][sudu[m][n][0]] = 0;
}
}
}
}
主函数
int main(int argc, char *argv[])
{
int i, n, j, k;
int id = 0;
ifstream ifp;
ofstream ofp;
N = atoi(argv[2]);
N = N + 1;
n = atoi(argv[4]);
ifp.open(argv[6]);
if (!ifp.is_open())//判断文件是否成功打开
cout << "File open failed" << endl;
ofp.open(argv[8]);
if (!ofp.is_open())
cout << "File open failed" << endl;
int count = 0;
while (n--)
{
for (i = 1; i < N; i++)
for (j = 1; j < N; j++)
//cin >> sudu[i][j][0];
ifp >> sudu[i][j][0];
for (i = 1; i < N; i++)
for (j = 1; j < N; j++)
for (k = 1; k < 10; k++)
sudu[i][j][k] = 1;
inti();
//cout << endl;
ofp << endl;
int q = 5;
while (q--)
{
for (i = 1; i < N; i++)
{
for (j = 1; j < N; j++)
if (sudu[i][j][0] == 0)
inti();
}
for (i = 1; i < N; i++)
for (j = 1; j < N; j++)
if (sudu[i][j][0] == 0)
count++;
if (count == 0)
break;
count = 0;
}
for (i = 1; i < N; i++)
for (j = 1; j < N; j++)
{
if (sudu[i][j][0] == 0)
id++;
}
if(id!=0)
solve(id);
for (i = 1; i < N; i++)
{
for (j = 1; j < N; j++)
{
//cout << sudu[i][j][0] << ' ';
ofp << sudu[i][j][0] << ' ';
}
//cout << endl;
ofp << endl;
}
}
return 0;
}
后来改进加了递归
void fill(int number, int i, int j) {
for (int k = 1; k < N; k++) {
sudu[i][k][number]++;
sudu[k][j][number]++;
}
/*for (int n = 0; n < 3; n++) {
for (int m = 0; m < 3; m++) {
sudu[i / 3 * 3 + n][j / 3 * 3 + m][number]++;
}
}*/
}
void reset(int number, int i, int j) {
for (int k = 1; k < N; k++) {
sudu[i][k][number]--;
sudu[k][j][number]--;
}
/*for (int n = 0; n < 3; n++) {
for (int m = 0; m < 3; m++) {
sudu[i / 3 * 3 + n][j / 3 * 3 + m][number]--;
}
}*/
}
void solve(int id)
{
if (id == 0)
return;
for (int i = 1; i < N; i++)
{
for (int j = 1; j < N; j++)
{
if (sudu[i][j][0] == 0)
{
for (int number = 1; number < 10; number++)
{
if (sudu[i][j][number] == 0)
{
number(number, i, j);
sudu[i][j][0] = number;
solve(id - 1);
sudu[i][j][0] = 0;
number(number, i, j);
}
}
return;
}
}
}
}
结果
等等!七八宫格现在还有点小问题...正在拼命解决
性能分析
cpu使用率
性能向导
我也不知道上面的对不对...
总结
我想说的是,太难了555,是我太菜了。
总的来说还是学到了真的学到了,对我来说都是新的。回头想想从刚开始的我肯定做不出来这题,到现在大概完成的还行,心里还是感到满足的。不过我却的东西还是太多了,以后还是不要害怕难题吧,像这次我就害怕了几天到现在时间就特别不够用了。
以后一定加油!