• 结对作业(返回一个整数数组中最大子数组的和——数组首尾相接)


    实验要求:

    结对开发伙伴:

    姓名:陶雨洁

      博客名:-相勖

      博客地址链接:http://www.cnblogs.com/Amyheartxy/p/6635165.html

    一、设计思想

    因为原来的算法,无法进行下去,查了百度,出现了更加简单的算法。是从数组的第一个数开始,初始最大值和当前和为第一个数;往后累计相加,如果遇到负数,则一定和为变小,则直接放弃原来的下标,从当前位置开始相加;如果当前和比最大值还大,最后一个下标也变为当前下标;然后一个for即可实现。

    二、出现的问题

    刚开始的时候是错误的思想,因为时间复杂度是O(n*n),不满足要求;而且只能计算特定结构的数组。(不小心删了原来错误的程序,没有保存。)

    之后,又发现在网上查到的代码,也有不足之处,它是循环了两遍,不符合要求。

    错误代码:

    package Test;
    
    import java.util.Scanner;
    
    public class test_c {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
        /*    System.out.print("请输入数组的长度N=");
            Scanner scan=new Scanner(System.in);
            int length=scan.nextInt();
            int arr[]=new int[length];
            for(int i=0;i<length;i++)
            {
                arr[i]=(int)(10-Math.random()*20);  //产生-10到10的随机数
                }*/
            int length=5;
            int arr[]={6,-3,-2,8,-4};
            int arr2[]=new int[2*length];
            for(int i=0;i<2*length;i++){
                if(i<length)
                {arr2[i]=arr[i];}
                else{
                    arr2[i]=arr[i-length];
                }
            }
            System.out.print("数组:{ ");
            for(int i=0;i<length;i++){System.out.print(arr[i]+" ");}//用于验证数组
            System.out.println("}");
            int max=0;
            int curSum=0;
            int M[]=new int[length];
            for(int j=0;j<2*length;j++)
            {
                if(j==0)
                {
                    max=arr2[j];
                    curSum=max;
                    continue;
                    }
                if(curSum<0)
                {
                    curSum=0;
                    }
                curSum+=arr2[j];
                if(curSum>max)
                {
                    max=curSum;
                    }
                }//for_l
            /*M[s]=max;
            int NA=Largest(M,length);
            System.out.println("最大子数组的和为:"+NA);*/
            System.out.println("最大子数组的和为:"+max);
        }
        public static int Largest(int list[],int length)
        {
            int i,max;
            //如果为空
             max=list[0];
            for(i=0;i<=length-1;i++)
            {
                if(list[i]> max){
                    max=list[i];
                }
            }    
            return max;
        }
    }//end

    相应的错误结果如下:

    原因:这是因为此程序循环了两遍有重复,且长度超过数组的长度。

    三、可能的解决方案

    这就得将时间复杂度变为O(n*n),开始下标作为另一个for循环,每一次循环得到的max用一个长度为数组长度的整型数组来存储。最后求此数组的最大值即可。

     更正代码之后:

    package Test;
    
    import java.util.Scanner;
    
    public class test_c {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
        /*    System.out.print("请输入数组的长度N=");
            Scanner scan=new Scanner(System.in);
            int length=scan.nextInt();
            int arr[]=new int[length];
            for(int i=0;i<length;i++)
            {
                arr[i]=(int)(10-Math.random()*20);  //产生-10到10的随机数
                }*/
            int length=5;
            int arr[]={6,-3,-2,8,-4};
            int arr2[]=new int[2*length];
            for(int i=0;i<2*length;i++){
                if(i<length)
                {arr2[i]=arr[i];}
                else{
                    arr2[i]=arr[i-length];
                }
            }
            System.out.print("数组:{ ");
            for(int i=0;i<length;i++){System.out.print(arr[i]+" ");}//用于验证数组
            System.out.println("}");
            int max=0;
            int curSum=0;
            int M[]=new int[length];
            for(int s=0;s<length;s++)
            {
            for(int j=s;j<s+length;j++)
            {
                if(j==s)
                {
                    max=arr2[j];
                    curSum=max;
                    continue;
                    }
                if(curSum<0)
                {
                    curSum=0;
                    }
                curSum+=arr2[j];
                if(curSum>max)
                {
                    max=curSum;
                    }
                }//for_l
            M[s]=max;
            }
            int NA=Largest(M,length);
            System.out.println("最大子数组的和为:"+NA);
            //System.out.println("最大子数组的和为:"+max);
        }
        public static int Largest(int list[],int length)
        {
            int i,max;
            //如果为空
             max=list[0];
            for(i=0;i<=length-1;i++)
            {
                if(list[i]> max){
                    max=list[i];
                }
            }    
            return max;
        }
    }//end

    截图结果如下:

    四、正确源代码

    package Test;
    
    import java.util.Scanner;
    
    public class test03 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.print("请输入数组的长度N=");
            Scanner scan=new Scanner(System.in);
            int length=scan.nextInt();
            int arr[]=new int[length];
            for(int i=0;i<length;i++)
            {
                arr[i]=(int)(10-Math.random()*20);  //产生-10到10的随机数
                }
            int arr2[]=new int[2*length];
            for(int i=0;i<2*length;i++){
                if(i<length)
                {arr2[i]=arr[i];}
                else{
                    arr2[i]=arr[i-length];
                }
            }
            System.out.print("数组:{ ");
            for(int i=0;i<length;i++){System.out.print(arr[i]+" ");}//用于验证数组
            System.out.println("}");
            int max=0;
            int curSum=0;
            int M[]=new int[length];
            for(int s=0;s<length;s++)
            {
            for(int j=s;j<s+length;j++)
            {
                if(j==s)
                {
                    max=arr2[j];
                    curSum=max;
                    continue;
                    }
                if(curSum<0)
                {
                    curSum=0;
                    }
                curSum+=arr2[j];
                if(curSum>max)
                {
                    max=curSum;
                    }
                }//for_l
            M[s]=max;
            }//for_w
            int NA=Largest(M,length);
            System.out.println("最大子数组的和为:"+NA);
        }
        public static int Largest(int list[],int length)
        {
            int i,max;
            //如果为空
             max=list[0];
            for(i=0;i<=length-1;i++)
            {
                if(list[i]> max){
                    max=list[i];
                }
            }    
            return max;
        }
    }//end

    五、结果截图

    验证①:

    验证②:

    验证③:

    验证④:

     

    六、总结

    1.编程的思想很重要,如果想错一步,则后面就很难改过来。

    2.结对编程时,时间可能不及单独一个人编程那么有效,但是却可以交流思想,使得编程变得有趣,相互督促。

  • 相关阅读:
    洛谷 P1024 一元三次方程求解
    洛谷 P1025 数的划分
    假期一测
    洛谷 P1032 字符变换
    洛谷 P1033 自由落体
    洛谷 P1063 能量项链
    洛谷 P1072 Hankson 的趣味题
    洛谷 P1040 加分二叉树
    1013: [JSOI2008]球形空间产生器sphere
    1013: [JSOI2008]球形空间产生器sphere
  • 原文地址:https://www.cnblogs.com/xiaxiaoshu/p/6637076.html
Copyright © 2020-2023  润新知