软件工程第三次作业

软件工程第三次作业

一、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;
	}
}

这样做只能每次调用对象的方法只能从头开始读,所以如果有两个以上的输出就不行了。

1

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;
}

等找到更好的方法在修改一下把

五、测试数据


六、性能测试

原文地址:https://www.cnblogs.com/klaycf/p/11586478.html