软件工程第三次作业
软件工程第三次作业
一、Github地址
二、PSP开发时间预估
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 30 | 25 |
Estimate | 估计这个任务需要多少时间 | 500 | 300 |
Development | 开发 | 10 | 10 |
Analysis | 需求分析 (包括学习新技术) | 45 | 120 |
Design Spec | 生成设计文档 | 15 | 30 |
Design Review | 设计复审 | 25 | 20 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
Design | 具体设计 | 5 | 1 |
Coding | 具体编码 | 240 | 200 |
Code Review | 代码复审 | 20 | 45 |
Test | 测试(自我测试,修改代码,提交修改) | 10 | 8 |
Reporting | 报告 | 5 | 10 |
Test Repor | 测试报告 | 15 | 10 |
Size Measurement | 计算工作量 | 2 | 1 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 10 | 12 |
合计 | 947 | 822 |
三、解题思路
在刚看到题目的时候,被这大段大段的文字给唬住了。反复看了几次之后,我的头绪也在脑海里慢慢理清了。抛开其他的要求来看,题目本身并不难。甚至有种很熟悉的感觉,在以前在写算法的时候,棋盘类的题目通常都是用回溯法来做的。类似的题目有刘汝佳的《算法竞赛入门经典》中的八皇后问题。这道题不过是多出了解的打印,多加了一些判定条件。想清楚这些之后,要考虑怎么用面对对象的方法解这道题。
构建类
class Sodoku
{
private:
int G[10][10];//数独矩阵
int l;//阶数
bool ok;//判断有无解
public:
void solve(int n);//求解主程序
bool check(int num,int value);//判定
void print_ans();//输出
void Init(int x); //初始化
void read();//读入
};
主要求解函数
用了回溯法,并在回溯时恢复现场。
因为只求一个解所以可以设置标记位,当求解成功后直接返回,加快运行速率。
void Sodoku::solve(int n)
{
if(n==l*l-1){
ok=1;
return ;
}
// de(n);
int x=n/l,y=n%l;
if(G[x][y]!=0)solve(n+1);
else {
// dd(x);dd(y);de(n);
for(int i=1;i<=l;i++){//从1-l尝试答案
// de(l);
if(check(n,i)){
G[x][y]=i;
// print_ans();cout<<endl;//分布显示数独矩阵
// de(l);
solve(n+1);//递归
if(ok)return;//回溯如果有解直接返回
}
}
G[x][y]=0;return;
}
}
先在本地运行
先把输入文件存在in.txt中
本地不用加txt害我卡了好久
学习如何用命令行读入文件
在看了几个大佬的博客后,知道了可以用以下的方法读入
int main(int argc, char *argv[]) {
/*从命令行接收参数 */
l = atoi(argv[2]);
int m = atoi(argv[2]);
int n = atoi(argv[4]);
四、遇到的难题
1.ifstream只在main函数运行
fstream fin;
fin.open(argv[6]);
后来发现如果这样做的画,类里面的定义的read()和print_ans()函数没法用文件流输入。
2.借鉴了大佬的思想,把文件路径用指针传入函数
void Sudoku::print_ans(const char* filename)
{
fstream fout;
fout.open(filename);
// cout<<l<<endl;
for(int i=0;i<l;i++){
for(int j=0;j<l;j++){
// cout<<G[i][j]<<" ";
fout<<G[i][j]<<" ";
}
// cout<<endl;
fout<<endl;
}
}
这样做只能每次调用对象的方法只能从头开始读,所以如果有两个以上的输出就不行了。
3.只能把输入输出操作放在main函数里了
int main(int argc,char* argv[])
{
int T=atoi(argv[4]);
int x=atoi(argv[2]);
ifstream fin(argv[6]);
ofstream fout(argv[8]);
Sudoku sudoku;
while(T--){
sudoku.Init(x);
for(int i=0;i<x;i++){
for(int j=0;j<x;j++){
fin>>sudoku.G[i][j];
}
}![](https://img2018.cnblogs.com/blog/1458245/201909/1458245-20190925181233416-1498474340.png)
sudoku.solve(0);
for(int i=0;i<x;i++){
for(int j=0;j<x;j++){
fout<<sudoku.G[i][j];
}
fout<<endl;
}
fout<<endl;
}
fin.close();
fout.close();
return 0;
}
等找到更好的方法在修改一下把
五、测试数据