软件工程第二次作业(完整版)
GitHub地址(之前太粗心,没有看到要生成txt文件这个要求,后来重新上传了一次。)
项目需求
利用程序随机构造出 N 个已解答的数独棋盘 。
输入
数独棋盘题目个数 N
输出
随机生成 N个不重复的已解答完毕的数独棋盘,并输出到 sudoku.txt中
——引用自《第二次作业——个人项目实战[http://www.cnblogs.com/vertextao/p/7472376.html]》
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 100 | 100 |
Development | 开发 | 300 | 300 |
· Analysis | · 需求分析 (包括学习新技术) | 60 | 30 |
· Design Spec | · 生成设计文档 | 60 | 0 |
· Design Review | · 设计复审 (和同事审核设计文档) | 30 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 0 |
· Design | · 具体设计 | 60 | 60 |
· Coding | · 具体编码 | 180 | 120 |
· Code Review | · 代码复审 | 120 | 120 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 120 |
Reporting | 报告 | 60 | 60 |
· Test Report | · 测试报告 | 60 | 30 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 60 | 120 |
合计 | 1160 | 1130 |
心路历程:
1、初看题目,我的第一想法是在每个位子随机生成数字,生成随机的矩阵,然后设置限定条件只输出符合数独的,转念一想这个工作量似乎有点大,会做很无用功。于是我百度了一下,想看看有没有什么生成数独的方法比较省力,可以借鉴一下,然而,网上关于这个几乎都是代码,看来人工解数独也没有什么好方法呀。
2、于是我自己想了一个方法,就是将数独分为几个部分,不单独分开来比对宫格内是否重复,而是在填入数字的时候放在一起判断。嗯……这个方法,想起来很直白,我觉得可能也许会快一点。于是我开始洋洋洒洒地写了起来,准备先把框架写出来,最后再debug,然而写完后根本就de不过来……这下就尴尬了,以下是当时代码的部分遗体:
int judge1(int i)
{
for(j=1;j<=9;j++)
{
if(j==1||j==2||j==3)
{
if(a!=shudu[i-1][1]&&a!=shudu[i-1][2]&&a!=shudu[i-1][3])
return 1;
else
return 0;
};break;
if(j==4||j==5||j==6)
{
if(a!=shudu[i-1][4]&&a!=shudu[i-1][5]&&a!=shudu[i-1][6])
return 1;
else
return 0;};break;
if(j==7||j==8||j==9)
{
if(a!=shudu[i-1][7]&&a!=shudu[i-1][8]&&a!=shudu[i-1][9])
return 1;
else
return 0;};break;
}
}/*判断生成数与上一层三列是否相同*/
3、向上面这么~~能打~~乱七八糟的函数,我写了四个,所以浪费了很多时间,我决定把这个锅甩给写的时间太晚。但是我还是学到了:开始写代码之前,应该先有清晰的思路,不能总是期待最后再来de bug。于是后来我决定推到重来,后来第二次写的想法是,把第一个位子先通过学号生成出来,这是固定的,然后生成与第一个数字不一样的第一行余下各个位子。接着从第二行第一列开始,通过递归,一个一个比对下去,先比对行,再比对列,接着先找到每个宫格的边界格子,再进行遍历宫格的9个位子,共有九个宫格。这是比对的代码:
#include <time.h>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
int sudoku[10][10];
int N, i, j,u,v;
int main()
{
freopen("sudoku.txt", "w+", stdout);
int fn = (1 + 4) % 9 + 1;
int star(int i, int j);
cin >> N;
srand((unsigned)time(NULL));//以当前系统时间生成随机数
for (int m = 0; m<N; m++)
{
for (i = 1; i <=9; i++)
{
for (j = 1; j <=9; j++)
sudoku[i][j] = 0;
} //初始化数独矩阵
for (i = 1; i <= 9; i++)
{
sudoku[1][i] = i; //按序生成第一行
}
sudoku[1][1] = fn;
sudoku[1][fn] = 1;
random_shuffle(&(sudoku[1][2]), &(sudoku[1][9])); //第一行第一个数交换为6,使后八个数随机排列
star(2, 1); //调用star函数,从第二行第一个数开始生成数独矩阵
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
cout << sudoku[i][j] << " ";
cout << endl;;
}//输出生成的数独矩阵
cout << endl;
}
return 0;
}
int star(int i, int j)
{
int same;
if (i > 9 || j > 9)
{
return 1;
}
for (int a = 1; a <= 9; a++)
{
same = 1;
for (int b = 1; b<i; b++)
if (a == sudoku[b][j])
{
same = 0;
break;
}//检测上下有无重复
if (same)
{
for (int n = 1; n<j; n++)
if (a == sudoku[i][n])
{
same = 0;
break;
}//检测左右有无重复
}
if (same)
{
int x = (i / 3) * 3 + 3;
int y = (j / 3) * 3 + 3; //找到宫格的边界格子
if (i % 3 == 0)
{
x = i;
}
if (j % 3 == 0)
{
y = j;
}
for (u = x - 2; u <= x; u++) //检查宫格中有无重复
{
if (same == 0)
break;
for (v = y - 2; v <= y; v++)
if (a == sudoku[u][v])
{
same = 0;
break;
}
}
}
if (same)
{
sudoku[i][j] = a;
if (j<9)
{
if (star(i, j + 1)) //跳到此行的下一列
return 1;
}
else
{
if (i < 9)
{
if (star(i + 1, 1)) //跳到此列下一行
return 1;
}
else
return 1; //当行或列数超过9时结束
}
sudoku[i][j] = 0;
}
}
return 0;
}
性能分析:
总结:
这周因为补考的事情迟交了,忘了挺多东西的,因为这个代码是之前写好的,印象很深的一点就是不能莽,要好好构思了再开始写代码,不然会做很多无用功,效率极低,然后就是学会了用效能分析工具。
第几周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 500 | 500 | 19 | 19 | 学会了用效能分析工具 |