zoukankan      html  css  js  c++  java
  • 现代程序设计 homework-02

    首先显示博客要求:

    描述在这么多相似的需求面前, 你怎么维护你的设计 (父类/子类/基类, UML, 设计模式,  或者其它方法) 让整个程序的架构不至于崩溃的?

    建议从后往前来搞,比如我通读一遍需求后了解到后面会用到多种模式,那么在输入的时候自然要定义后mode然后一步一步来,这里用的是面向过程的设计方法,所以没有用到面向对象的那么多冗杂的概念,程序的架构主要是根据不同的mode分别进行相应的输入错误判断,然后调用不同的Input函数完成输入,init()函数完成初始化操作,最后通过不同的work()函数完成函数主体操作

    给出你做单元测试/代码覆盖率的最终覆盖率的报告, 用截屏显示你的代码覆盖率

    。。。。我的作业2是用C++的面向过程方法写的。。。无法进行单元测试。。。今天我做完了作业3。。。。用C#实现。。。尝试着用单元测试。。。

    结果出现了这个东东

    难道是告诉我只能有Form类可以进行单元测试么....虽然代码写的偏面向过程....也不用这个样子吧....所以这次没有这一项...或者说这次的代码不适合进行单元测试...我进行了其他方面的测试...证明了我的代码比较挫...至于Bug..从零开始学c#...调Bug 调了两天...应该质量可以的..

    阅读 工程师的能力评估和发展 和相关文章, 在完成作业的时候记录自己花费的时间, 并填下表。如果你对有些术语不太清楚,请查看教材和其它资料。如果你认为你不需要做某个步骤, 那就跳过去。

      Personal Software Process Stages 时间百分比(%)  实际花费的时间 (分钟) 原来估计的时间 (分钟)
    Planning 计划 3.3   45            60 
    ·         Estimate  ·         估计这个任务需要多少时间,把工作细化并大致排序  3.3  45 60 
    Development 开发 81.2   1100  840
    ·         Analysis  ·         需求分析 (包括学习新技术) 4.4   60  60
    ·         Design Spec ·         生成设计文档   0  0
    ·         Design Review ·         设计复审 (和同事审核设计文档)  0  0
    ·         Coding Standard ·         代码规范 (制定合适的规范)  0  0
    ·         Design ·         具体设计 8.9   120  60
    ·         Coding ·         具体编码 59.0   800  600
    ·         Code Review ·         代码复审 4.4   60  60
    ·         Test ·         测试(自我测试,修改代码,提交修改) 4.4  60  60
    Reporting 总结报告 15.5   210  60
    ·         Test Report ·         测试报告 8.9   120  0
    ·         Size Measurement ·         计算工作量 2.2   30  0
    ·         Postmortem & Improvement Plan ·         事后总结, 并提出改进 4.4   60  60
    Total 总计 100% 总用时 总估计的用时
           1355  960

    你在这个作业中学到了什么?  有什么好的设计值得分享?  感想如何 (太容易 / 太难 / 太无趣)?

    。。。感想绝对是太难。。

    其他的变形还算简单,但是关于最大联通子块自己一直没有想到好的做法,今天想了一天采用状压dp的做法一直无法得出正确的结果,原因在于我是采用按行dp的算法,那么在行与行之间进行转移的时候就出现了问题,我不知道该如何用代码表示两行之间存在相邻关系,这里我用二进制表示一行的状态,某位置0表示该位不取,置1表示该位取,那么对于相邻两行的二进制状态,我该如何表示它们的相邻关系呢?今天这一整天我想了无数的转移方法,但一个个的被我推翻,最后的最后我发现貌似我要采取更暴力的穷举状态了,那就是将每行的状态表示为一个数字,那么所有行的数字按位与之后所得的结果如果不为0就表示它们满足相邻关系,那么我就可以求出一个和,穷举所有行的所有状态,那么就可以求出一个最大值.好可怕的复杂度....记行数为n,每行m个数,那么对每一个行,状态有2^m种,复杂度就是O(2^(mn)),,一会儿去实现一下.

    昨晚找鲁大师请教了一下,他和我说这种题目叫做连通性状压dp,也就是插头dp,于是今天上午看了一会儿插头dp,可是这东西完全看不懂啊...代码那么一坨...于是今天思考了一下用暴力来解决这个问题.用01串来标记整个二维数组,枚举每一种状态,判断该状态是否满足连通性条件(采用dfs来判定),然后找最大值就好...复杂度大概为O(2^mn)....

    没有用面向对象的思想来做这个问题,导致代码有500行之多...好挫..

     

    吐槽完了,说一下代码思路

    首先根据命令行参数的数量以及各个string来判断mode,并且处理错误输入

    对于一维和二维普通情况,就是O(n)的最大子数组,方法不过多讲了,参加上一篇博客

     1 void maxsum1()//一维O(n)求最大子数组
     2 {
     3     long long tempsum=num[1];
     4     long long ans=tempsum;
     5     for(int i=2;i<=col;i++)
     6     {
     7         tempsum=max(num[i],tempsum+num[i]);
     8         ans=max(tempsum,ans);
     9     }
    10     printf("%lld
    ",ans);
    11 }
     1 void maxsum2()//二维最大子数组O(n^3)
     2 {
     3     init2();
     4     int tempans=map[1][1];
     5     int ans=tempans;
     6     for(int i=1;i<=row;i++)
     7     {
     8         for(int j=i;j<=row;j++)
     9         {
    10             tempans=getsum(i,1,j,1);
    11             for(int k=2;k<=col;k++)
    12             {
    13                 tempans=max(getsum(i,k,j,k),tempans+getsum(i,k,j,k));
    14                 ans=max(tempans,ans);
    15             }
    16         }
    17     }
    18     printf("%d
    ",ans);
    19 }

    对于一维左右联通情况,我们可以知道它的最大和要么是没有跨过了a[n]和a[1],要么是没有跨过;如果没有跨过,那么就是简单的一维普通情况,记最大值为ans1;如果跨过了,那么不妨设此时的最大子数组为a[j],a[j+1],....a[n],a[1],a[2],...a[i],i<j,此时可以证明a[i],a[i+1],....a[j]一定是最小子数组,并且a[i]和a[j]一定是小于0的(否则可以加到最大子数组中得到更优的解),那么我们扫描一遍的时候,只要同时记录最大子数组,最小子数组,和数组总和,那么ans=max(ans1,all-ans2);

    对于二维左右联通情况,只要先纵向压缩为一维,然后再调用就好

    对于二维上下联通情况,这里我想到了两种解决方法:一是可以在输入的时候将原来的数组转置,那么就变成了求左右联通的情况;二是可以在纵向压缩的时候不必保证上界小于下界,当枚举的下界小于上界的时候,此时的getsum求得的和其实是总的和减去上下界之间的和,然后情况又变成了普通的二维情况

     1 void maxsum3()//左右联通情况的最大子数组
     2 {
     3     init2();
     4     int sum1=sum[1][1];
     5     int sum2=sum[1][1];
     6     int all=sum[1][1];
     7     int tempmin=sum[1][1];
     8     int tempmax=sum[1][1];
     9     int ans=sum[1][1];
    10     for(int i=1;i<=row;i++)
    11     {
    12         for(int j=i;j<=row;j++)
    13         {
    14             sum1=sum2=tempmin=tempmax=all=getsum(i,1,j,1);
    15             for(int k=2;k<=col;k++)
    16             {
    17                 int temp=getsum(i,k,j,k);
    18                 all+=temp;
    19                 sum2=min(sum2+temp,temp);
    20                 /*
    21                 if(sum2<0)
    22                 {
    23                     sum2+=temp;
    24                 }
    25                 else
    26                 {
    27                     sum2=temp;
    28                 }
    29                 */
    30                 tempmin=min(tempmin,sum2);
    31                 sum1=max(sum1+temp,temp);
    32                 /*
    33                 if(sum1>0)
    34                 {
    35                     sum1+=temp;
    36                 }
    37                 else
    38                 {
    39                     sum1=temp;
    40                 }
    41                 */
    42                 tempmax=max(tempmax,sum1);
    43             }
    44             ans=max(max(tempmax,all-tempmin),ans);
    45             if(tempmin==all)
    46             {
    47                 ans=max(ans,tempmax);
    48             }
    49         }
    50     }
    51     printf("%d
    ",ans);
    52 }

    对于游泳圈的情况,就是把前两种总和起来考虑就好

     1 void maxsum5()//游泳圈形状的最大子数组
     2 {
     3     init2();
     4     int sum1=sum[1][1];
     5     int sum2=sum[1][1];
     6     int all=sum[1][1];
     7     int tempmin=sum[1][1];
     8     int tempmax=sum[1][1];
     9     int ans=sum[1][1];
    10     for(int i=1;i<=row;i++)
    11     {
    12         for(int j=1;j<=row;j++)
    13         {
    14             sum1=sum2=tempmin=tempmax=all=getsum(i,1,j,1);
    15             for(int k=2;k<=col;k++)
    16             {
    17                 int temp=getsum(i,k,j,k);
    18                 all+=temp;
    19                 sum2=min(sum2+temp,temp);
    20                 /*
    21                 if(sum2<0)
    22                 {
    23                     sum2+=temp;
    24                 }
    25                 else
    26                 {
    27                     sum2=temp;
    28                 }
    29                 */
    30                 tempmin=min(tempmin,sum2);
    31                 sum1=max(sum1+temp,temp);
    32                 /*
    33                 if(sum1>0)
    34                 {
    35                     sum1+=temp;
    36                 }
    37                 else
    38                 {
    39                     sum1=temp;
    40                 }
    41                 */
    42                 tempmax=max(tempmax,sum1);
    43             }
    44             ans=max(max(tempmax,all-tempmin),ans);
    45             if(tempmin==all)
    46             {
    47                 ans=max(ans,tempmax);
    48             }
    49         }
    50     }
    51     printf("%d
    ",ans);
    52     /*
    53     for(int i=1;i<=row;i++)
    54     {
    55         int len=(i>1?row-1:row);
    56         for(int j=i;j-i<len;j++)
    57         {
    58             int begin=1;
    59             int temp=0;
    60             for(int end=1;end<col*2&&begin<=col;end++)
    61             {
    62                 if(end-begin>=col)
    63                 {
    64                     end=++begin;
    65                     temp=0;
    66                 }
    67                 temp=max(0,temp+sum[j][end]-sum[i-1][end]);
    68                 if(temp<=0)
    69                 {
    70                     begin=end+1;
    71                 }
    72                 if(temp>ans)
    73                 {
    74                     ans=temp;
    75                 }
    76             }
    77         }
    78     }
    79     printf("%d
    ",ans);
    80     */
    81 }

    对于联通块,我的朴素解法已经在上面说明了,对于更高效率的插头dp解法我不会

      1 bool check(int x,int y)
      2 {
      3     if(x<0||x>=row||y<0||y>=col)
      4     {
      5         return false;
      6     }
      7     else
      8     {
      9         return true;
     10     }
     11 }
     12 void dfs(int x,int y,int choice)
     13 {
     14     visit[x][y]=1;
     15     for(int i=0;i<4;i++)
     16     {
     17         int tx=choice?(x+dx[i]+row)%row:x+dx[i];
     18         int ty=choice?(y+dy[i]+col)%col:y+dy[i];
     19         if(check(tx,ty)&&!visit[tx][ty]&&bit[tx][ty])
     20         {
     21             dfs(tx,ty,choice);
     22         }
     23     }
     24 }
     25 void anotherwork(int choice)
     26 {
     27     int ans=-INF;
     28     for(int i=0;i<row;i++)
     29     {
     30         for(int j=0;j<col-1;j++)
     31         {
     32             if(scanf_s("%d,",&map[i][j])!=1)
     33             {
     34                 printf("input matrix wrong!
    ");
     35                 exit(0);
     36             }
     37         }
     38         if(scanf_s("%d",&map[i][col-1])!=1)
     39         {
     40             printf("input matrix wrong!
    ");
     41             exit(0);
     42         }
     43     }
     44     int N=row*col;
     45     for(int i=0;i<(1<<N);i++)//枚举2^nm种状态 
     46     {
     47         for(int j=0;j<row;j++)
     48         {
     49             for(int k=0;k<col;k++)
     50             {
     51                 visit[j][k]=0;
     52                 bit[j][k]=0;
     53             }
     54         }
     55         for(int j=0;j<N;j++)
     56         {
     57             bit[j/col][j%col]=(i&(1<<j))>>j;
     58         }
     59         bool ok=true;
     60         for(int j=0;j<row;j++)
     61         {
     62             if(!ok)
     63             {
     64                 break;
     65             }
     66             for(int k=0;k<col;k++)
     67             {
     68                 if(bit[j][k])//找到第一个1点进行dfs标记该联通块 
     69                 {
     70                     dfs(j,k,choice);
     71                     ok=false;
     72                     break;
     73                 }
     74             }
     75         }
     76         ok=true;
     77         for(int j=0;j<row;j++)
     78         {
     79             if(!ok)
     80             {
     81                 break;
     82             }
     83             for(int k=0;k<col;k++)
     84             {
     85                 if(bit[j][k]&&!visit[j][k])
     86                 {
     87                     ok=false;
     88                     break;
     89                 }
     90             }
     91         }
     92         int s=-INF;
     93         if(ok)
     94         {
     95             s=0;
     96             for(int j=0;j<row;j++)
     97             {
     98                 for(int k=0;k<col;k++)
     99                 {
    100                     if(bit[j][k])
    101                     {
    102                         s+=map[j][k];
    103                     }
    104                 }
    105             }
    106             ans=max(ans,s);
    107         }
    108     }
    109     printf("%d
    ",ans);
    110 }

    PS:作业有要求对于错误输入要能够正确处理,结果我写了一个巨长的处理函数处理了未输入指定分隔符;输入数据不够多;输入数据太多===是不是想太多了..

     

  • 相关阅读:
    Centos定时执行python脚本
    python 版websocket实现
    Linux Shell脚本实现根据进程名杀死进程
    /bin/bash^M: bad interpreter: 没有那个文件或目录
    python标准日志模块logging的使用方法
    对线程的理解
    Python处理JSON(转)
    div 模糊效果
    C#线程访问winform窗体控件
    iOS开发中添加PrefixHeader.pch要注意的问题
  • 原文地址:https://www.cnblogs.com/oldoldb/p/3331975.html
Copyright © 2011-2022 走看看