2017软工实践第二次作业 --个人项目实战

GitHub 地址

软工实践第二次作业链接

因为git和vs以前做计算器的时候用过 使用起来还是蛮熟悉的。

解题思路

数独是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9,不重复。
数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。

简单的了解下数独就是每一行,每一列,每一小九宫格的数字均为1-9,且每个数字只出现一次不重复。

故这题就是用一个数组flag标记该位置是否可填数字,如果可填,通过get_next_num(int,int,int)找到可行数字并且填入到Sudoku[][]中去 ,然后进入下一层递归,如果获取不了就返回上一层递归。

解法No.1:刚开始我是想每次标记的时候都把整行,整列,以及整个小九宫格遍历一遍,寻找是否该数字可用,觉得这样子很耗时间。

解法No.2:现在我们在算法中用了 row_mark[][] col_mark[][] J_Gong_mark[][]三个数组来标记该行数字是否用过,该列数字是否用过,以及该小九宫格是否用过这数字。方便后面检查。
比如说某一行的某个数字用过就用数组 row_mark [第几行][哪一个数字] = 1 做标记
再比如说某一列的某个数字用过就用数组col_mark[第几列][哪一个数字] = 1 做标记
某一小九宫格的某个数字用过就用数组J_Gong_mark[第几个小九宫格][哪一个数字] = 1 做标记 //PS: 小九宫格位置计算 3*(行/3)+(列/3)
这样子我们可以减少查询次数,节省了一大部分时间。
flag[][]数组,它用来标记,哪些位置是可以填数的,换句话来说,哪些位置,在初始状态是空的。初始完后,我们用回溯法,从第一个位置开始寻找,从三个数组中找交集即(row_mark col_mark J_Gong_mark ) 也就是说这三个数组都没标记这个数字 说明该数字是可以用的,如果当前数可用,就进入下一层的递归,直到到达最后一个格子。

还有本算法可以通过递归找到你所需要填的的几个数独棋盘。由于我们每次寻找的都是可用数字,不用判断当前数是否符合规则。

代码

  
//进行回溯 加 遍历
void sudokulib::backdate(int x, int y) {
    if (y == 9) x++, y = 0;
    while (flag[x][y] && x <= 8) {
        y++;
        if (y == 9) {
            x++, y = 0;
        }
    }
    if (x > 8) {
        print();
        if (++cnt == N) {
            exit(-1);
        }
    }
    while ((sudoku_tmp[x][y] = get_next_num(x, y, sudoku_tmp[x][y] + 1)) != -1) {
        row_mark[x][sudoku_tmp[x][y]] = 1;
        col_mark[y][sudoku_tmp[x][y]] = 1;
        J_Gong_mark[3 * (x / 3) + (y / 3)][sudoku_tmp[x][y]] = 1;   //说明该数字可以用 
        backdate(x, y + 1);
        row_mark[x][sudoku_tmp[x][y]] = 0;
        col_mark[y][sudoku_tmp[x][y]] = 0;
        J_Gong_mark[3 * (x / 3) + (y / 3)][sudoku_tmp[x][y]] = 0;   //说明该数字不能用  还原到前一个状态 
    }
}

运行结果

1068184-20170910170241569-205730303.png

1068184-20170910170356741-20351136.png

性能测试

以下是我跑100W数据的性能分析:

1068184-20170910175045444-1120591699.png
从图中可以看出该程序还是挺慢的 !!跑100W数据都得6分多钟。感觉要改进的话就应该用数字字符,可能跑的速度会快一点。

1068184-20170910210540085-1381484622.png

单元测试

这一块还不怎么懂,看百度一些资料1 资料2自己也尝试了,一直调试不出结果。Orz......

简简单单的记录

.初次记录 有点乱 也不知道什么作用 希望后面能明白 迷迷糊糊....

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

心得体会

做这个任务的时候发现已经快开学了,所以自己也提前回学校来学习如何处理这个任务,也去看了很多资料,看了很多前辈们的做法和优化。在这个过程中最让人头疼的是使用vs做性能测试和单元测试,到现在为止单元测试还是没搞明白,但在这过程中还是学会了蛮多的,至少现在看到了vs的强大(可能还有更强大的功能需要我们在这过程中慢慢去发觉),我觉得这才刚刚开始,接下来会更好玩........

转载于:https://www.cnblogs.com/suefen/p/7498058.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值