• 软件工程实践2017第二次作业【数独】


    作业地址
    GitHub


    在初看到题目时我是又惊又喜,喜是应该我从小就很喜欢玩数独,惊是因为题目看起来难度不小,但是如果太简单又能学到什么呢?在做作业的过程中我遇到了很多困难,也学到了很多。

    遇到的困难及解决方法

    • 困难描述

      我这次使用的是C#语言,由于以前写算法多是使用C和C++,C#用来写界面,用C写算法对我来说难度不小,有很多函数不懂,很多情况不知道怎么处理,性能也很差。
    • 做过哪些尝试

      首先我是想到用回溯法生成数独,网络上也有很多人用这种方法,看了一些C++写的,然后想着自己也写写看。
    • 是否解决
      在写的过程中,我发现自己写的性能很差,但是修改了很久没有改变,我只好暴力求解。
    • 有所收获
      感觉经过这几天自己特别努力地在学习,学习了各种知识,自己的综合学习能力也有所提升。

    PSP表格

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

    解题思路

    刚拿到题目的时候,我想到可以用回溯法做,一行一行的填过去,但是想了一下一行一行地填效率是否太低了,又想到要判断没有九宫格都有数字有些麻烦,就想到不如我一个一个九宫格填过去,每次填一个数字,填九次就填完了,同时还不用验证一个九宫格里是否有重复的数字,只要比较行和列就可以了。

    设计实现

    程序里有两个类,一个是Map,是数独有关的类,里面有三个函数,另一个是Program类,执行程序的类,里面有五个函数。
    流程图:

    关键代码

    
    static bool Fill(int s, int d, ref Map a,ref int count)//将数字随机填入九宫格(fill the Nine Patch with each number)
    {
    
              int i, j, m, n;
    
              Random ran = new Random(Guid.NewGuid().GetHashCode());
    
              for (j = 0; j < 6; j++)
    
              {
    
                    i = ran.Next(0, 9);//随机生成一个九宫格中的位置(randomly generate the position to fill in Nine Patch)
    
                    m = Yp[s] + yp[i];
    
                    n = Xp[s] + xp[i];
    
                    if (a.sdk[m, n] == 0 && a.x[n] == 0 && a.y[m] == 0)//判断是否可以填入数字(determine if the number can be filled in)
    
                    {
    
                        count++;//每次填入时count+1(count + 1 every time you fill in)
    
                        a.sdk[m, n] = d;
    
                        a.y[m] = 1;
    
                        a.x[n] = 1;
    
                        a.m[s] = 1;
    
                        return true;
    
                    }
    
              }
    
              return false;
    
    }
    
    

    我把数独分成九个九宫格,利用随机数生成九宫格的位置,填入数字,利用一个count,如果反复填入过多,那就跳出循环。

    
     while (a.m[s] == 0)
    
     {
    
          if (!Fill(s, d, ref a,ref count))
    
           {
    
                  if (count > 500) return;//count大于500时跳出循环(drop the loop when count>500)
    
                  s=Back(s, d, ref a);
    
                  continue;
    
             }
    }
    
    static int Back(int s, int d, ref Map a)//当一个九宫格填不下去时,回到上一个九宫格(when you can't put the number in this Nine Patch,go back to the previous one)
    {
    
              int i, m, n;
    
              if (s == 0) return s;
    
              else s--;
    
              a.m[s] = 0;
    
              for (i = 0; i < 9; i++)
    
              {
    
                    m = Yp[s] + yp[i];
    
                    n = Xp[s] + xp[i];
    
                    if (a.sdk[m, n] == d)
    
                    {
    
                        a.sdk[m, n] = 0;
    
                        a.y[m] = 0;
    
                        a.x[n] = 0;
    
                        return s;
    
                      }
    
                }
    
                return s;
    }
    
    

    当一个九宫格无处可填的时候,回到上一个九宫格再随机填。

    测试运行

    性能分析

    数据:2000

    占比最多的函数是填入九宫格Fill函数,最多的是生成随机数填入,我本来想用两个随机数,一个生成填入的x轴坐标,一个生成填入的y轴坐标,但是生成随机数太费时间了,我就生成一个随机数,用数组让一个随机数定位到填入的位置。

  • 相关阅读:
    2.2 范式和反范式
    1.7 关系数据库设计理论
    2.1 选择优化的数据类型
    1.6 间隙锁(next-key locking)
    1.5 MySQL的存储引擎
    1.4 多版本并发控制
    1.3 事物和并发一致性问题
    1.2 并发控制
    1.1 MySQL逻辑架构
    php自定义函数及内部函数----数组处理函数
  • 原文地址:https://www.cnblogs.com/yujohn/p/7502786.html
Copyright © 2020-2023  润新知