• 高级软件工程第二次作业


    1.Github地址 xinz

    2.解题思路:

        一开始拿到这道题的时候,对数独的概念不是那么清晰。通过题目中百度百科的概念,即被概括成满足以下三个条件的数字范围为1-9的棋盘:(1)每一行不能有重复的数字(2)每一列不能有重复的数字(3)9乘9的大数独盘被划分成9个3乘3的小九宫格,在每个小九宫格内不能有重复数字
        按照人脑填数独的思维我们很容易想到“枚举”的方法,即从填第2个数开始递归填写观察是否满足三个条件,依次往下填写输出一个结果棋盘后进行“回溯”。所以这种“暴力的”程序还是比较简单易懂的,通过百度也了解到其他算法,比如交换行列、用随机数生成等等,但都不如枚举来的直接易懂。
        •从第二个格子开始,根据数独需要满足的三个条件从1-9枚举填数字,并同时标记该格子内哪些数字试过了
        •对剩下的格子进行递归操作
        •输出一个结果棋盘后将记录该数字是否存在的数组复原,为下一次试数做准备,进行回溯,重复上述操作
        •直到满足所需棋盘个数,结束
        途径:百度 + 自己思考 + 同学帮忙
    

    3.设计实现过程

    3.1流程图:

    3.2设计思路:

        对输入的格式进行处理,使其输入格式为“sudoku.exe -c 生成数独个数”,封装在input_check函数中
        输出在outfile函数中,当输出所需个数的数独棋盘后结束
        枚举试数字的方法(回溯)在sudoku函数中 
    

    4.代码说明

    int input_check(int argc, char *argv[])
    {
    	if (argc != 3)
    	{
    		cout << "invaild input" << endl;
    		return -1;
    	}
    	if (argc == 3 && strcmp(argv[1], "-c") != 0)
    	{
    		cout << "please input -c" << endl;
    		return -1;//如果输入第二个参数不是-c 不输出
    	}
    	if (atoi(argv[2]) == 0)
    	{
    		cout << "please enter a value greater than 0" << endl;
    		return -1;//如果输入第三个参数不是数字 不输出
    	}
    	return atoi(argv[2]);
    }
    
    //用递归生成数独,nrow表示当前行,ncol表示当前列,表示当前正在处理第nrow行第ncol列的格子。
    void shudu(int nrow, int ncol, ofstream &savefile)
    {
    	//计算该格子在哪个九宫格中
    	int nowbox = ((nrow - 1) / 3) * 3 + ((ncol - 1) / 3 + 1);
    	//对该格子进行1-9的数字尝试,如果nownum==num则说明棋盘已经够了,就不用再进行下去了,循环退出
    	for (int i = 1; i <= 9 && nownum<num; i++)
    	{
    		//如果数值i在该行该列没有出现过,则进行下一步操作
    		if (row[nrow][ran_num[i]] == 0 && column[ncol][ran_num[i]] == 0 && box[nowbox][ran_num[i]] == 0)//判定数值i在该行该列该九宫格有没有出现过
    		{
    			result[nrow][ncol] = ran_num[i];//把数值i填写入最终棋盘
    			row[nrow][ran_num[i]] = column[ncol][ran_num[i]] = box[nowbox][ran_num[i]] = 1;//记录下i这个值在该行该列和该九宫格出现了
    			//如果这个格子是最后一个格子了,说明已经找到一个数独棋盘
    			if (nrow == 9 && ncol == 9)
    			{
    				nownum++;//已找到的数独棋盘数量+1
    				if (nownum == num) outfile(savefile, true);//这个是最后一个棋盘
    				else outfile(savefile, false);//这不是最后的棋盘
    			}
    			//如果这个格子不是最后一个格子,则对下一个格子进行枚举
    			else
    			{
    				if (ncol == 9) shudu(nrow + 1, 1, savefile);//如果这个格子是该行最后一个格子,则换行
    				else shudu(nrow, ncol + 1, savefile);//如果这个格子不是该行最后一个格子,则处理该行下一个格子
    			}
    			row[nrow][ran_num[i]] = column[ncol][ran_num[i]] = box[nowbox][ran_num[i]] = 0;//递归完后复原,为下一个数字的尝试做准备
    		}
    	}
    }
    
    
    //把当前的数独棋盘输出到文件,savefile为输出文件流,islast表示当前输出的棋盘是否为最后一个棋盘
    void outfile(ofstream &savefile, bool islast)
    {
    	string temp = "";//用来临时保存需要输出的文字
    	for (int i = 1; i <= 9; i++)
    	{
    		for (int j = 1; j <= 9; j++)
    		{
    			if (j != 1) temp += " ";//每个数字之间需要一个空格
    			temp += result[i][j] + '0';//把每个数字转换成字符
    		}
    		temp += "
    ";//输出完一行需要换行
    	}
    	if (!islast) temp += "
    ";//如果这个不是最后一个棋盘,棋盘间需要再次换行。
    	savefile << temp;//把文字输入到文件中
    }
    

    5.测试运行


    6.效能分析

    n=1000时

    7.PSP

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

    8.心得体会

    这是第一次尝试使用Github工具,以及在markdown的排版上也花了一定时间。从拿到题目百度到后期自己思考、请教同学,也花了很多时间。希望以后的项目自己可以越做越顺利!

  • 相关阅读:
    Sublime Text shift+ctrl妙用(转载)
    编写一致的符合习惯的javascript
    Vue 部署单页应用,刷新页面 404/502 报错
    http 缓存策略浅析
    Vue 项目优化,持续更新...
    web安全之——XSS、CSRF
    javascript 易错知识点合集
    深入理解 js this 绑定机制
    javascript 模块依赖管理的本质
    VUE 项目刷新路由指向index.html
  • 原文地址:https://www.cnblogs.com/linlkg/p/7642003.html
Copyright © 2020-2023  润新知