实验要求:
结对开发伙伴:
姓名:陶雨洁
博客名:-相勖
博客地址链接: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.结对编程时,时间可能不及单独一个人编程那么有效,但是却可以交流思想,使得编程变得有趣,相互督促。