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


    1)Github项目地址:
    the address of github

    2)PSP 2.1表格:

    PSP

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

    3)解决思路描述:

    • ①首先,任务描述为:

    用程序随机构造出N个已解答的数独棋盘。(根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。)

    根据这个条件的话感觉很简单,即构造一个9*9数组,并根据对应的三个条件确定每个位置上要填的数字。
    
    • ②因为有新增要求如下

    2017.9.4 新增要求] 在生成数独矩阵时,左上角的第一个数为:(学号后两位相加)% 9 + 1

    所以改变思路,先满足第一行第一个数,再去随机生成其他数字。
    

    4)设计实现过程:

    • ①初始化一个9*9数组,每个位置都为0,[0][0]位置置为要求的数字。
    • ②先随机生成第一行。
    • ③从第二行第一个位置开始迭代,根据对应的三个条件确定数字。
    • ④未找到满足条件的数字时,回溯到前一个位置并重新填数。(重点)

    5)代码说明:

    • ①随机生成第一行及判断输入
    int main(int argc,char* argv[])
    {
    	string ss = argv[2];
    	int len = ss.length();
    	for (int i = 0; i < len;i++) {
    		if (ss[i]<'0' || ss[i]>'9') {
    			printf("error input");
    			return 0;
    		}
    		else {
    			N = N * 10 + ss[i] - '0';
    		}
    	}
    	freopen("sudoku.txt","w",stdout);
    	srand((unsigned)time(NULL));
    	sudoku[0][0] = 9;
    	for (int i = 1; i<9; i++)
    	{
    		sudoku[0][i] = i;
    	}
    	random_shuffle(&(sudoku[0][1]), &(sudoku[0][8]));
    	produce_sudoku(1, 0, 1);
    	return 0;
    }
    
    • ②判断是否满足条件
    bool judge(int line,int column,int a,int sudoku[9][9])
    {
    	int x,y;
    	for(int i=0; i<9; i++)//行判断 
    	{
    		if(sudoku[line][i]==a)
    		{
    			return false;
    		}
    	}
    	for(int i=0; i<9; i++)//列判断 
    	{
    		if(sudoku[i][column]==a)
    		{
    			return false;
    		}
    	}
    	x = (line/3)*3;
    	y = (column/3)*3;
    	for(int i=x; i<x+3; i++)//九宫格判断 
    	{
    		for(int j=y; j<y+3; j++)
    		{
    			if(sudoku[i][j]==a)
    			{
    				return false;
    			}
    		}
    	}
    	return true;
    }
    
    • ③依次判断及回溯
    void produce_sudoku(int i,int j,int z)
    {
    	if (j < 0)
    	{
    		i--;
    		j=0;
    	}
    	if(j>8)//换行 
    	{
    		i++;
    		j=0;
    	}
    	if(i==9&&j==0)
    	{
    		for(int k=0; k<9; k++)
    		{
    			for(int l=0; l<9; l++)
    			{
    				cout << sudoku[k][l] << " ";
    			}
    			cout << endl;
    		}
    		cout<<endl;
    		if (--N <= 0)
    		{
    			exit(0);
    		}
    	}
    	else if (i < 9) //z的作用为防止生成重复矩阵 
    	{
    		for(int kk=1;kk<9;kk++){
    		int n = (z++)%9 + 1;
    		if(judge(i,j,n,sudoku))
    		{
    			sudoku[i][j] = n;
    			produce_sudoku(i,j+1,z);//----回溯 ---- 
    			sudoku[i][j] =0;//----回溯 ---- 
    		}
    	}
    	} 
    }
    

    6)测试运行(DEV)

    • ①N=1000:

    • ②N=10000:

    7)效能分析(100W):

    报告分析:
    时长主要耗在produce_sudoku函数中的回溯过程,代码执行效率和算法有待提高。

  • 相关阅读:
    kafka常见问题汇总
    kafka可视化工具kafkatool
    VB.NET DevExpress GirdView 搜素框界面Find Clear按钮转换为自定义中文
    winform DevExpress GridView复制单元格方法
    DevExPress GridView获取单元格坐标和内容
    Winform Log4Net使用(一)(产生yyyyMMdd'.log)便于每天使用记录一眼能看出哪天使用时出错
    winform 判断重复检测,是否开启相同应用程序 和 线程异常捕获
    winfrom Run状态控件刷新办法
    C# winform Panel自定义移动窗口
    C# 控制台CMD辅助类
  • 原文地址:https://www.cnblogs.com/How-Come/p/7501919.html
Copyright © 2020-2023  润新知