博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第二次作业——个人项目实战
阅读量:6294 次
发布时间:2019-06-22

本文共 3131 字,大约阅读时间需要 10 分钟。

第二次作业——个人项目实战

项目需求

利用程序随机构造出N个已解答的数独棋盘 。

输入

数独棋盘题目个数N(0<N<=1000000)

输出

随机生成N个不重复的已解答完毕的数独棋盘,并输出到sudoku.txt中,输出格式见下输出示例。

[2017.9.4 新增要求] 在生成数独矩阵时,左上角的第一个数为:(学号后两位相加)% 9 + 1。例如学生A学号后2位是80,则该数字为(8+0)% 9 + 1 = 9。

遇到的困难及解决方法

  • 对于数独理解不够深刻,通过百度查找资料,了解到数独是99的棋盘中,每行每列以及每个33的九宫格中均不重复的填入1到9这九个数字;并且找到几个数独终盘观察棋盘特点。
  • 自己用纸和笔倒是能一步一步达到数独终盘,但是让计算机来完成任务,我觉得这一直以来是我面临的最大问题!
    -只能从最初步一点点思考,题目有要求说在第一个格子中填入特定的数字,顺其自然知道了第一行和第一列其他位置不再存在特定数字,直接在第一个格子中直接填入数字。
    • 比较容易想到的机器做法就是一个一个填入,在同学的提示下,意识到每填入一个数字,要对其进行行、列、宫的重复判断,如果重复了,需要退回上一个格子中重新填入,返回则需要用到递归函数,成功填入一个数字,则进入下一个递归函数,填入失败,退回上一个递归函数中。

关键代码&设计说明

void sudoku::getarea(){    for (int i = 1; i <= 9; i++) {         for (int j = 1; j <= 9; j++) {              int a = (i - 1) / 3;              int b = (j - 1) / 3;              area[i][j] = a + b * 3 + 1;          }    }}
  • 在将99的整个棋盘分为9个33的小九宫格后,每个区域给一个标号分别为1到9,可通过上述函数计算出每个格子所在的区域。(ps:好吧,我承认我不太理解为什么能如此计算区域,感恩大佬相助。)
void sudoku::wrNum(int x, int y){    if (flag)return;    if (x < 9 || y < 9) {        int a = x;        int b = y + 1;        if (b > 9) {            b = 1;            a++;        }        int p = area[a][b];        int t = rand() % 9 + 1;        int r = t;        while (1) {            if (!row[a][r] && !column[b][r] && !place[p][r]) {                sudo[a][b] = r, row[a][r] = 1, column[b][r] = 1, place[p][r] = 1;                wrNum(a, b);                sudo[a][b] = 0, row[a][r] = 0, column[b][r] = 0, place[p][r] = 0;            }            r++;            if (r == 10)r = 1;            if (t == r)break;        }    }    else {        sum++;        for (int i = 1; i <= 9; i++) {            for (int j = 1; j <= 9; j++) {                cout << sudo[i][j];                if (j < 9)cout << " ";            }            cout << endl;        }        if (sum != n)cout << endl;        if (sum == n)flag = true;    }}
  • 上述函数即为填数的递归函数,row、column、place三个二维数组为判断当前行、列、宫是否存在当前要填的随机数。若行存在,则row当前位置为1,不存在为0,列和宫类比。若遇到数字重复的情况,填入的随机数自动加1,然后再次尝试填入,若循环一轮都不能填入,则退回上一层递归函数,另外只能填入1到9,当自加为10时,变为1,尝试填入。当行和列都填入超过9时,则开始输出,当输出个数与输入要求个数相同时,则退出本函数。
sudoku::sudoku(){    memset(row, 0, sizeof(row));    memset(column, 0, sizeof(column));    memset(sudo, 0, sizeof(sudo));    memset(place, 0, sizeof(place));    sum = 0;    flag = false;}
  • 前文提到过要判断即将填入的随机数是否在当前行、列、宫中已存在,并通过三个二维数组记录情况,且最终形成的棋盘只存在1到9数字,所以将所有二维数组初始化为零,并不影响后续操作。

运行效果:

890238-20170910174501210-2867861.png

性能分析

890238-20170910174843069-1707458085.png

890238-20170910174858022-1428326390.png

890238-20170910174907257-191017630.png

PSP表格

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

个人总结

  • 不得不承认第一次完成大项目作业,感觉一个人完成难度颇大,多亏得到了周围同学不厌其烦的帮助,一点一点,挤牙膏般勉勉强强的完成了。主要体现出的问题是如何设计算法使得计算机能够完成要求的计算内容,遇到瓶颈时容易撞南墙不回头,要学习其他同学“绕路”解决问题的方式。另外,由于算法遇到了瓶颈,在翻阅大量博客的过程中,偶然间加到了一位博友,他现在已经参加工作,他自述现在主要在做前端方面,编程方面过去一直在做,我认为在写博客,阅览博客,认识到更多代码大神更是一份珍贵的财富。

转载于:https://www.cnblogs.com/yangguanghaitian/p/7500889.html

你可能感兴趣的文章
查找、替换与定位
查看>>
解决莫名其妙出现connection closed的错误
查看>>
Linux多线程实践(3) --线程属性
查看>>
Catalyst3550交换机配置三层接口
查看>>
Elixir语言
查看>>
Java Calendar 类的时间操作
查看>>
esxi所连交换机划vlan导致vm不能通讯
查看>>
关于CE端口线路整改的建议
查看>>
如何禁止使用本地administrator进行共享连接
查看>>
用python解析html[SGMLParser]
查看>>
hive执行流程(3)-Driver类分析1Driver类整体流程
查看>>
Android开发学习笔记:对话框浅析
查看>>
Ajax学习-Ajax简介
查看>>
下载备忘:甘特图实现的代码
查看>>
Linux文本比较命令:diff
查看>>
redux-form的学习笔记二--实现表单的同步验证
查看>>
小评 XenServer 6.0功能
查看>>
Android中获取屏幕的宽和高
查看>>
ACL访问控制列表
查看>>
Lync Server 2010迁移至Lync Server 2013故障排错Part1:缺少McsStandalone.msi
查看>>