目的:一个整数数组中的元素有正有负,在该数组中找出一个连续子数组,要求该连续子数组中各元素的和最大,这个连续子数组便被称作最大连续子数组。
输入:随机产生1000以上的数据(有正有负),放入输入文件
输出:比如数组{2,4,-7,5,2,-1,2,-4,3}的最大连续子数组为{5,2,-1,2},最大连续子数组的和为5+2-1+2=8。
为了简单的看结果,我将数组长度定义为10。老规矩,算法很简答,没什么难度,不懂就问。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Main {
public static int maxSubSum3(int[] a) {
if(a.length<1){
return 0;
}else{
return subSum3(a, 0, a.length - 1);
}
}
private static int subSum3(int[] a, int left, int right) {
if (left == right)
if (a[left] > 0)
return a[left];
else
return 0;
//先找到数组的中心位置
int center = (left + right) / 2;
//递归求中心位置左边的最大子序列之和
int maxLeftSum = subSum3(a, left, center);
//递归求中心位置右边的最大子序列之和
int maxRightSum = subSum3(a, center + 1, right);
//求带着中心位置情况下左边的最大子序列之和
int maxLeftBorderSum = 0, leftBorderSum = 0;
for (int i = center; i >= left; i--) {
leftBorderSum += a[i];
if (leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
//求带着中心位置情况下右边的最大子序列之和
int maxRightBorderSum = 0, rightBorderSum = 0;
for (int i = center + 1; i <= right; i++) {
rightBorderSum += a[i];
if (rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
//比较三者之间最大的值
return Math.max(Math.max(maxLeftSum, maxRightSum), maxLeftBorderSum + maxRightBorderSum);
}
public void Write() throws IOException{
int num;
int[] a=new int[10];
for(int i=0;i<a.length;i++){
num=(int) (Math.random()*100*(Math.random()>0.5?1:-1));
a[i]=num;
}
File file=new File("D:\\in.txt");
FileWriter out = new FileWriter(file);
for(int i=0;i<a.length;i++){
out.write(a[i]+"\t");
}
out.close();
}
public int[] Read() throws IOException{
int[] b=new int[10];
File file=new File("D:\\in.txt");
BufferedReader in=new BufferedReader(new FileReader(file));
String line=in.readLine();
String[] temp=line.split("\t");
for(int j=0;j<temp.length;j++){
b[j]=Integer.parseInt(temp[j]);
}
in.close();
return b;
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
int[] c=new int[10];
Main m=new Main();
m.Write();
c=m.Read();
long startTime=System.currentTimeMillis();
int q=maxSubSum3(c);
long endTime=System.currentTimeMillis();
System.out.println("分治策略方法:" + q);
System.out.println("时间为:"+(endTime-startTime)+"ms");
}
}