zoukankan      html  css  js  c++  java
  • 《返回一个整数数组中最大子数组的和》团队合作及第六周学习进度条

    团队合作第一棒:输入一个一维整形数组,数组里有正数也有负数。一维数组首尾相接,象个一条首尾相接带子一样。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。
    一、设计思想:
      1.最初,在设计循环数组之前,运用maxsum和maxstart来对遍历最大子数组过程中的最大值进行更新与保存,主要设计思路是:将两个值分别赋予数组的第一个数,然后对所输入的数组的值进行逐次遍历,maxstart进行数组中值的相加,如果maxstart大于maxsum,及时进行更新maxsum的值,如果maxstart的值过小,则将之前的数组中的值进行丢弃,将自己赋为0,加上数组中的下一个值(即直接赋予数组中的下一个数值),重新比较,依次更新,最后获得最大的sum值。
      2.老师将要求修改为循环数组后,于是将maxsum设为全局变量,数组扩大了一倍(即将所输入的数组重复导入所定义数组中),增设了一个循环,就是将初始值分别设为数组中的每一个数,然后依次向后循环加上(所设数组长度)个值,原理同上,但时间复杂度变为了平方。
      3.要想使得时间复杂度为n,增设了判断数值正负的函数、单个最大值函数,之后沿用以前的思路,问题得以解决。
    二、出现的问题:
      1.for循环下如果用if来使得max与数组为1,2,3......n的子数组进行比较,n不能确定,所以数组求和遇到问题。于是边求和边比较,子数组的和用一个变量来进行存储,最大值用另一个变量进行存储,收尾相接需要注意子数组的和,否则会超过子数组所应存在的范围。
      2.子数组和的数目可能会超过原来数组和的数目,用变量jishu来控制,k记录是第几次超过,超过之后maxstart,jishu重置为0,循环从k+1开始。
      3.如果都是负数,maxstart赋初值为0会大于数组本身,单个元素的最大值即为最大子数组。
    三、可能的解决方案:
      可能的解决办法同上述设计思想与可能遇到的问题。
    四、源代码:
    (以下第一个源代码的时间复杂度为O(n方))
    import java.util.Scanner;
    public class maxShuZu {
    	public static int maxsum;
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
            int i,j;
            int maxstart;
            Scanner in=new Scanner(System.in);
            System.out.println("请输入数组的大小:");
            int number=in.nextInt();
            int array[]=new int[number*2];
            System.out.println("请输入数组的值:");
            for(i=0;i<number;i++)
            {
            	array[i]=in.nextInt();
            	array[i+number]=array[i];
            }
        	maxsum=array[0];
            for(j=0;j<number;j++){
                maxstart=array[j];
                for(i=j+1;i<j+number;i++){
                	if(maxstart<0){
                		maxstart=0;
                	}
                	maxstart+=array[i];
                	if(maxstart>maxsum){
                		maxsum=maxstart;
    	            }
    	        }
            }
            System.out.println("最大子数组的和为:"+maxsum);
            in.close();
    	}
    }
    

    经过修改,将源代码的时间复杂度改为了O(n)

    代码如下:

    import java.util.Scanner;
    public class max {
        public static int maxsum;
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int i,j,jishu,k;
            boolean flag=true;//判正负
            int maxstart = 0;
            Scanner in=new Scanner(System.in);
            System.out.println("请输入数组的大小:");
            int number=in.nextInt();
            int array[]=new int[number*2];
            System.out.println("请输入数组的值:");
            for(i=0;i<number;i++)
            {
                array[i]=in.nextInt();
                array[i+number]=array[i];
            }
            
            //---判断数组是否全为负数
            flag=Pan(array);
            if(flag)
            {
                maxsum=Max(array);
            }
            
            //---
            maxsum=array[0];
            jishu=0;//子数组数
            k=0;//第几次达到最大数组数
            for(j=0;j<2*number-1;j++){
                maxstart+=array[j];
                jishu++;
      
                if((maxstart<0)){
                    
                        maxstart=0;
                        jishu=0;
                
                }
                if(jishu>number)
                {
                    if(k<number)
                    {
                        jishu=0;
                        j=k;//经过k++从下一轮开始
                        maxstart=0;
                        k++;
                    }
                    
                }
                if(maxstart>maxsum){
                    maxsum=maxstart;
                }
            }
            System.out.println("数组:");
            for(i=0;i<number*2-1;i++)
            {
                System.out.print(array[i]+" ");
            }
            System.out.println("最大子数组的和为:"+maxsum);
            in.close();
        }
    
        public static boolean Pan(int[] array)
        {
            boolean flag=true;
              for(int i=0;i<array.length;i++)
                {
                    if(array[i]>0)
                    {
                        flag=false;
                        break;
                    }
                }
            return flag;
            
        }
        public static int Max(int[] array)
        {
            int max=array[0];
            for(int i=0;i<array.length;i++)
            {
                if(array[i]>max)
                    max=array[i];
            }
            return max;
        }
    }

     之后又对代码进行了完善,如下:

    import java.util.Scanner;
    
    public class maxArray {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
      
             int i=0,maxsum=0;
             boolean flag=true;
             
             Scanner in=new Scanner(System.in);
             System.out.println("请输入数组的大小:");
             int number=in.nextInt();
             int array[]=new int[number*2-1];
             System.out.println("请输入数组的值:");
             for(i=0;i<number;i++)
                {
                    array[i]=in.nextInt();
                    if(i<number-1)
                    {
                        array[i+number]=array[i];
                    
                    }
                }
             
             flag=Pan(array);
             
             if(flag==true)
             {
                 maxsum=Max(array);
             }
             else
             {
                 maxsum=sumMax(array,number);
             }
             System.out.println("数组:");
                for(i=0;i<array.length;i++)
                {
                    System.out.print(array[i]+" ");
                }
                System.out.println("最大子数组的和为:"+maxsum);
                in.close();
        }
        //-----最大子数组的和
        public static int sumMax(int[] array,int number)
        {
            int i,jishu=0,k=0;//jishu 控制子数组个数,k记录第几次到达最大数组数
            int maxstart=0;//子数组和的初始值
            int maxsum=array[0];//初始值
              for(i=0;i<array.length;i++){
                    maxstart+=array[i];
                    jishu++;
                    if((maxstart<0)){
                        {
                            maxstart=0;
                            jishu=0;
                        }
                    
                    }
                    if(jishu>number)
                    {
                        if(k<number)
                        {
                            jishu=0;
                            i=k;//经过k++从下一轮开始
                            maxstart=0;
                            k++;
                        }
                        
                    }
                    if(maxstart>maxsum){
                        maxsum=maxstart;
                    }
        
            }
            return maxsum;
        }
        //----判断数组是否全为负数,true 正数,false 负数
        public static boolean Pan(int[] array)
        {
            boolean flag=true;
            for(int i=0;i<array.length;i++)
            {
                if(array[i]>0)
                {
                    flag=false;
                }
            }
            return flag;
        }
        //------单个最大值
        public static int Max(int[] array)
        {
            int max=array[0];
            for(int i=0;i<array.length;i++)
            {
                if(array[i]>max)
                {
                    max=array[i];
                }
            }
            return max;
        }
    }

    五、结果截图:

    六、总结:这次的结对合作,的确让我受益匪浅,能够明白思想碰撞的火花的重要性,另外编写程序要有一个清晰的思路,不能提笔就写,盲目没有好下场,所以今后的代码之路一定要慎思笃行,学会和别人合作,并在团队中要发挥作用,从中获取知识。

    本次实验由井小普和张贺合作完成,在数组进行循环之后如何处理子数组,并求出最大子数组的和进行了交流。

    第六周学习进度条:

  • 相关阅读:
    XML Schema的基本语法(转)
    Lambda 表达式参考
    LINQ查询表达式示例
    Jackson ObjectMapper类使用解析
    hdu 1242 c++ 广搜
    poj 1111 新手路过
    poj 1664 放苹果
    poj 3126 简单广搜题
    poj 1256 全排列
    HDU 2544 最短路
  • 原文地址:https://www.cnblogs.com/zhangjiabei/p/6646420.html
Copyright © 2011-2022 走看看