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

实验要求:

结对开发伙伴:

姓名:陶雨洁

  博客名:-相勖

  博客地址链接: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.结对编程时,时间可能不及单独一个人编程那么有效,但是却可以交流思想,使得编程变得有趣,相互督促。

原文地址:https://www.cnblogs.com/xiaxiaoshu/p/6637076.html