计算给定数组的最大连续子数组和
一、 问题描述
1、元素个数不超过100个,存储在文本文件中。
2、元素具有首尾相接特点。
3、输出结果:
(1)求出的最大子数组和
(2)该子数组在原数组中的位置(起始下标和结束下标)
二、代码展示
public void test() {
int[] a=getNumbers();
int n = a.length;
int[] a1=findMaxSum(a,n);
int b,temp,i,left = 0,right=0,sum=0;
int[] a3;
for(b=1;b<n;b++)
{
temp=a[0];
for(i=1;i<=n-1;i++)
{
a[i-1]=a[i];
}
a[n-1]=temp;
a3 = findMaxSum(a,n);
if(a3[2]>=sum)
{
sum=a3[2];
left=a3[0]+i-1;
right=(a3[1]+i-1)%n;
}
}
int a2=sum;
if(a1[2]>=a2)
{
System.out.println("最大子数组和:" + a1[2] +"左坐标为:"+a1[0] +"右坐标为:" + a1[1]);
}
else
{
System.out.println("最大子数组和:" + a2+"左坐标为:"+ left+"右坐标为:" +right);
}
}
public static int[] findMaxSum(int a[],int n)
{
int[] result=new int[3];
int sum=0;
int b=0;
int left =0;
int right = 0;
for(int i=0;i<n; i++)
{
if(b<0){
b=a[i];
left=i;}
else
b+=a[i];
if(sum<b){
sum=b;
right=i ;
}
}
result[0]=left+1;
result[1]=right+1;
result[2]=sum;
return result;
}
public int[] getNumbers() {
int[] n = new int[0];
String s = "text";
String numbers = "";
FileInputStream fi = null;
try {
int count;
fi = new FileInputStream(s);
byte[] bytes = new byte[4];
while ((count = fi.read(bytes)) != -1) {
numbers += new String(bytes, 0, count);
}
String[] strings = numbers.split(",");
n=new int[strings.length];
for (int i = 0; i < strings.length; i++) {
n[i] = Integer.parseInt(strings[i]);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (s != null) {
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return n;
}
三、项目总结
算法设计:用的时间较长,选择了多个方法,对其时间复杂度和空间复杂度进行估计和考量,算法的实现难度也有所考虑,得出两个方案。
编码设计:4个小时,因选择第一种算法后期改代码太困难,因而改了第二种算法,易于理解,代码简单。
1、折中算法,时间复杂度较低,设计思想:最大子数组只有三种可能,把数组从中间分为左数组和右数组,最大子数组要么在左数组中,要么在右数组中,还有一种情况是跨越左右两个数组,分别求出左右中三种情况下的最大子数组,对其和进行比较,返回最大值为结果。
2、基本算法,时间复杂度较高,循环嵌套次数多,思想简单,易于实现。首尾相连采用嵌套负值的方法把所有可能性数组遍历出来,再将每个数组调用计算最大子数组函数,对比每个结果,返回最大结果。
单元测试:
花费时间3小时,最大子数组右下角标right出现错误较多,输入多组数据对每个数的流程进行测试,发现right=i的位置放的不对,因而出现某些特殊数据时会有错误出现。
总结:项目实现首先要在头脑中理清思路,对要用的方法进行分析设计,最好做出流程图,单元测试的时候要用覆盖面广的数据,多试几组,避免出现算法错误。
测试出错时要用多组会出错的代码对算法进行测试,根据结果即可推算出错误出现的位置。
四、遇到的问题
下角标的算法出现问题,数组循环后如何保持输出结果下角标为原数组下角标而非对应数组下角标。
五、总结认知
1、理论认知变化
阶段审批是非常有必要的,每个阶段完成的任务都要确认是否能得到预期的结果。
2、方法认知变化
方法需要根据问题要求分析可得,从整体到结构再到层次进行分析。
3、技术认知变化
一定要有编码基础,算法分析能力,选择覆盖广的数据来测试方法。
六、心得体会
一定要有耐心,懂得分析思考,学会设计算法,出现问题时要找到错误的位置并分析如何修改解决。