软件工程实践2017第二次作业

===================

一、GitHub地址:https://github.com/xiaoknownothing/Fzuwork

二、遇到的困难及解决方法

 一看到这个题目感觉可以选定一个空位,扫看所在行,所在列,所在宫,排除数字后选择数字填入,最好的情况所在行列的数字全部填满,这样就简单多了。可是这个数独棋盘只有一个数已知,其他的位子都有9个数要去“猜测”,每行每列每宫格子内数字还不重复,顿时脑子有点大,忙着搜索了一下,看了一些博客,才有了一些大概方向。

三、解题思路

用回溯法求解数独:

  • 1.从找第一个空的位子开始,找可选数(排除同行同列同宫重复的数),逐个放入
  • 2.找下一个空的位置,找可选数填入,如果这时候,发现此处空白格没有可选数,就回溯,换掉前面的可选数,再继续执行2
  • 3.直到空位子都满了就是一个数独解出来了
    //找出area[x][y]的可选数
vector <int> find(int x, int y) 
{
	int a[10] = { 0 };
	vector <int> ret;//声明一个int型向量ret 
	for (int i = 0; i < 9; i++)
	 {
		if (sudu[i][y] > 0) 
		a[sudu[i][y]] = 1;//所在行若有其他数,标记已使用 
		if (sudu[x][i] > 0)
	    a[sudu[x][i]] = 1; //所在列若有其他数,标记已使用 
		
	}
	int row = x / 3, col = y / 3;//所在宫若有其他数,标记已使用 
	for (int i = row * 3; i < row * 3 + 3; i++)
	{ 
		for (int j = col * 3; j < col * 3 + 3; j++)
		 {
			if (sudu[i][j] > 0) 
			a[sudu[i][j]] = 1;
		}
	}
	for (int i = 1; i <= 9; i++) 
	{
	if (!a[i]) ret.push_back(i);//逐个填入剩余可选数 
    }
	return ret;
}
void update() {
	for (int i = 0; i < 81; i++) area[i].clear();
	chosen = make_pair(0, 10);
	can_update = false;
	for (int i = 0; i < 9; i++	)
	{
		for (int j = 0; j < 9; j++) if (sudu[i][j]==0) 
		{
			int k = i * 9 + j;//k为该空白格序号 
			area[k] = find(i, j);//填入可选数 
			if (area[k].empty()) is_blank = false;//没有可选数 
			if (area[k].size() < chosen.second) chosen = make_pair(k, area[k].size());//更新 
			can_update = true;
		}
	}
}
void num_sudu() 
{
	update();
	if (can_update==false)
	 {
		num++;
		if (num >=N) is_over = true;
		print();
	}
	else if (is_blank==false) 
	{
		return;
	}
	else if (is_over==false)
	 {
		int areaition = chosen.first;
		int x = areaition / 9;
		int y = areaition - x * 9;//x,y为该位置坐标 
        int size = chosen.second;//size为选中数个数 
		vector <int> k = area[areaition];
		for (int i = 0; i < size; i++) 
		{
			sudu[x][y] = k[i];
			num_sudu();
			sudu[x][y] = 0;
			is_blank = true;
			// 回溯, 还原数据, 原is_blank, 前面的深搜,都没有正确答案,会导致is_blank=false
		}
	}
}

四、测试

  • 运行测试

五、PSP

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 15 40
· Estimate · 估计这个任务需要多少时间 15
Development 开发
· Analysis · 需求分析 (包括学习新技术) 400 600
· Design Spec · 生成设计文档
· Design Review · 设计复审 (和同事审核设计文档)
· Coding Standard · 代码规范 (为目前的开发制定合适的规范)
· Design · 具体设计 240 260
· Coding · 具体编码 180 200
· Code Review · 代码复审 30 40
· Test · 测试(自我测试,修改代码,提交修改) 60 80
Reporting 报告 30 130
· Test Report · 测试报告 30
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60
合计 640 1360

posted @ 2017-09-10 22:57  lxipandas  阅读(186)  评论(1编辑  收藏  举报