[软件工程学习笔记]结对作业---最大子数组问题

 

     今天的软件工程课老师让我们结对的小组现场来完成一个小程序。

      题目: 输入一个整型数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。

       我和永哥随即进入紧张的讨论,和大多数同学一样,很短的时间内谁也没有顾及时间复杂度的问题,首先要对每相邻的数组进行求和,然后再将求和的结果与max最大值进行比较,若大于则互换继续比较。在求和的问题上,我们将每个元素顺序跟后面相邻的元素相加,需要用到三个for循环,很短的时间内,我们一致同意用这个算法来解决,以便可以在当堂完成程序。

       大神就是大神,永哥编程从来不打草稿,只需灵机一动,一串代码就能浮现在他脑子里。我们的讨论在短短五分钟内就结束了,只上除了潦草的几个方块和曲线再也没有其他。永哥最擅长的语言是java,用起来收放自如得心应手,而在java上,我只算是个初学者,只能在一旁试图跟上他的节奏。

       他首先建了一个SumObject类:其中定义了和sum和数组下标indexs。

 1 package cn.stdu.edu.cn.domin;
 2 
 3 public class SumObject {
 4     private int sum;
 5     private String indexs;
 6     
 7     public SumObject(int sum,String indexs)
 8     {
 9         this.sum=sum;
10         this.indexs=indexs;
11     }
12     public int getSum() {
13         return sum;
14     }
15     public void setSum(int sum) {
16         this.sum = sum;
17     }
18     public String getIndexs() {
19         return indexs;
20     }
21     public void setIndexs(String indexs) {
22         this.indexs = indexs;
23     }
24 }

首先是一个求和的函数,具体的思路就是将每一个数都与剩下相邻的数进行求和,这样就用到了三个for循环语句。

 1 public void sum(int number[])
 2     {    
 3         int sum=0;
 4         String indexs="";
 5         for(int i=0;i<number.length;i++)
 6         {
 7             for(int j=0;j<number.length;j++)
 8             {
 9                 for(int n=i;n<=j;n++)
10                 {
11                     sum=sum+number[n];
12                     indexs=indexs+n;
13                 }
14                 SumObject sumObject=new SumObject(sum,indexs);
15                 sum=0;
16                 indexs="";
17                 sumList.add(sumObject);
18             }
19         }
20     }

     二十分钟到了,我们的位置互换,接下来编写的任务就落在了我的头上,下面的任务就是对所求的和进行比较找出最大的进行输出,另外在java语句上的问题永哥对我也有一些指点,虽然在语言上并不熟悉,但还是顺利的完成了。

 1 public SumObject MaxOfSum()
 2     {
 3         int max=0;
 4         String indexs="";
 5         for(int i=0;i<sumList.size();i++)
 6         {
 7             if(max<sumList.get(i).getSum())
 8             {
 9                 max=sumList.get(i).getSum();
10                 indexs=sumList.get(i).getIndexs();
11             }
12         }
13         SumObject sumObject=new SumObject(max,indexs);
14         return sumObject;
15     }

最后加入main函数检验我们的结果:

1 public static void main(String[] args) {
2         int num[]={-1,-2,3,60,-7,9,11,-32};
3         SearchMaxSum searchMaxSum=new SearchMaxSum();
4         searchMaxSum.sum(num);
5         SumObject sumObject=searchMaxSum.MaxOfSum();
6         System.out.println(sumObject.getSum()+"    "+sumObject.getIndexs());
7     }

运行结果:

76    23456

前面一项是最大和,后面一项是数组下标。

========================================

以上是我们课堂上的过程,在课下我们对这道题的时间复杂度的问题上对算法再次进行了讨论。

如果对第一个元素其到第n个元素的值是负数或零,则不必考虑其与后面的元素相加,直接将前面的和归零,从下一个元素开始再和后面的元素进行相加。反之继续相加得出最大值。这样我们就得到了一个复杂度为线性的算法。不必浪费时间去对每一种情况进行分析。机智的永哥以光速按照我们后来的思想写下了如下代码,简单粗暴,直接有效。

 1 /**  
 2     * @Name: bestSearchMaxSum
 3     * @Description: 在求子数组的最大和
 4     * @Author: 张永&吴盈盈
 5     * @Version: V1.00 
 6     * @Create Date: 2014-3-10 
 7     * @Parameters:整型数组number[],SumObject对象maxSumObject
 8     * @Return: SumObject对象
 9     */
10     
11     public SumObject bestSearchMaxSum(int number[], SumObject maxSumObject)   
12     {  
13         int i;  
14         int max=0; 
15         String indexStart=""; 
16         String indexEnd="";
17         for ( i = 0; i < number.length; i++ )  
18         {  
19             if ( (max= number[i] + max) > 0 )  
20             {  
21                 indexEnd = i+"";  
22             }  
23             else  
24             {  
25                 indexStart = ""+(i + 1);   
26                 max = 0;  
27             }  
28             if ( max > maxSumObject.getSum() )   
29             {  
30                 maxSumObject.setSum(max);  
31             }  
32         }  
33         maxSumObject.setIndexs(indexStart+indexEnd);
34         return maxSumObject;
35     }

=================================

我们本次课堂作业也算圆满的完成了。在这次作业的过程中突然想起前几日看老师给推荐的《人月神话》这本书上提到的一个经验法则:

对软件任务的进度安排:

1/3计划    1/6编码   1/4构建测试和早期系统测试   1/4系统测试,所有的构建已完成

后两者对于我们来说还尚早。但前两者已经很能说明问题。

在课上我们用五分钟来对算法进行计划,然后用四十分钟写出了一个时间复杂度较高的程序,显然这并不符合这个经验法则,对于我们来讲也是走了弯路浪费了更多的时间。急于求成往往会是丢了西瓜捡了芝麻。可能编码对于我来说还有很大的问题,但是这终究不是设计一个程序中最主要的问题所在,以后应当培养更加灵活的思维,给之后的工作做好万全的准备。

转载于:https://www.cnblogs.com/wingwyy511/p/3592527.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值