分治算法,最大子数组问题??
我按照算法导论写的代码,给定1,3,1,-1,我觉得应该输出5,也就是1,3,1,而算法给出结果是4,有1,3构成。为什么?
package b;
public class FindMaxCrossingSub {
static int nosum=0;
public static final int MAXLEFTID=0,MAXRIGHTID=1,MAXSUM=2;
public static int[] crossSub(int[] A,int low,int mid,int right){
int sum=0;
int[] cross=new int[3];
int leftSum=0,rightSum=0;
int maxLeft=0,maxRight=0;
//find maxleft
for(int i=mid;i>=low;i--){
sum+=A[i];
if(sum>leftSum){
leftSum=sum;
maxLeft=i;
}else{
leftSum=0;
maxLeft=mid;
}
}
//find maxright
sum=0;
for(int i=mid+1;i<=right;i++){
sum+=A[i];
if(sum>rightSum){
rightSum=sum;
maxRight=i;
}else{
rightSum=0;
maxRight=mid;
}
}
//modify value array
cross[MAXLEFTID]=maxLeft;
cross[MAXRIGHTID]=maxRight;
cross[MAXSUM]=leftSum+rightSum;
System.out.println("leftsum:"+leftSum+",rightsum:"+rightSum);
return cross;
}
public static void print(int[] temp){
for(int i=0;i<temp.length;i++){
System.out.println("no "+i+":"+temp[i]);
}
}
public static int[] findMax(int[] A,int left,int right){
nosum++;
System.out.println("第"+nosum+"次递归调用:"+"left:"+left+"right:"+right);
//System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());
int mid;
int[] valueArray=new int[3];
int[] leftArray=new int[3];
int[] rightArray=new int[3];
int[] crossArray=new int[3];
if(left==right){
valueArray[MAXLEFTID]=left;
valueArray[MAXRIGHTID]=right;
valueArray[MAXSUM]=A[left];
return valueArray;
}else{
mid=(int) Math.floor((left+right)/2);
leftArray=findMax(A,left,mid);
rightArray=findMax(A,mid+1,right);
crossArray=crossSub(A,left,mid,right);
if((leftArray[MAXSUM]>rightArray[MAXSUM])&&(leftArray[MAXSUM]>crossArray[MAXSUM]))
return leftArray;
else if((rightArray[MAXSUM]>leftArray[MAXSUM])&&(rightArray[MAXSUM]>crossArray[MAXSUM]))
return rightArray;
else return crossArray;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] value=new int[3];
int[] c={1,3,1,-1};
print(c);
value=findMax(c,0,c.length-1);
//print(cross);
System.out.println("---max subArray---");
for(int i=value[0];i<=value[1];i++)
System.out.println("A["+i+"]:"+c[i]);
System.out.print("最大子数组和为:"+value[2]);
}
}
package b;
public class FindMaxCrossingSub {
static int nosum=0;
public static final int MAXLEFTID=0,MAXRIGHTID=1,MAXSUM=2;
public static int[] crossSub(int[] A,int low,int mid,int right){
int sum=0;
int[] cross=new int[3];
int leftSum=0,rightSum=0;
int maxLeft=0,maxRight=0;
//find maxleft
for(int i=mid;i>=low;i--){
sum+=A[i];
if(sum>leftSum){
leftSum=sum;
maxLeft=i;
}else{
leftSum=0;
maxLeft=mid;
}
}
//find maxright
sum=0;
for(int i=mid+1;i<=right;i++){
sum+=A[i];
if(sum>rightSum){
rightSum=sum;
maxRight=i;
}else{
rightSum=0;
maxRight=mid;
}
}
//modify value array
cross[MAXLEFTID]=maxLeft;
cross[MAXRIGHTID]=maxRight;
cross[MAXSUM]=leftSum+rightSum;
System.out.println("leftsum:"+leftSum+",rightsum:"+rightSum);
return cross;
}
public static void print(int[] temp){
for(int i=0;i<temp.length;i++){
System.out.println("no "+i+":"+temp[i]);
}
}
public static int[] findMax(int[] A,int left,int right){
nosum++;
System.out.println("第"+nosum+"次递归调用:"+"left:"+left+"right:"+right);
//System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());
int mid;
int[] valueArray=new int[3];
int[] leftArray=new int[3];
int[] rightArray=new int[3];
int[] crossArray=new int[3];
if(left==right){
valueArray[MAXLEFTID]=left;
valueArray[MAXRIGHTID]=right;
valueArray[MAXSUM]=A[left];
return valueArray;
}else{
mid=(int) Math.floor((left+right)/2);
leftArray=findMax(A,left,mid);
rightArray=findMax(A,mid+1,right);
crossArray=crossSub(A,left,mid,right);
if((leftArray[MAXSUM]>rightArray[MAXSUM])&&(leftArray[MAXSUM]>crossArray[MAXSUM]))
return leftArray;
else if((rightArray[MAXSUM]>leftArray[MAXSUM])&&(rightArray[MAXSUM]>crossArray[MAXSUM]))
return rightArray;
else return crossArray;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] value=new int[3];
int[] c={1,3,1,-1};
print(c);
value=findMax(c,0,c.length-1);
//print(cross);
System.out.println("---max subArray---");
for(int i=value[0];i<=value[1];i++)
System.out.println("A["+i+"]:"+c[i]);
System.out.print("最大子数组和为:"+value[2]);
}
}
...全文
相关推荐
c语言实现分治算法求解最大子数组
自己写的分治算法,也包括了暴力求解的部分,并比较两者的运行时间,输出最大子数组的起始位置
利用分治策略求解最大子数组问题
最大子数组问题是计算机科学中一个著名的问题,它要求在一个给定的整数数组中找到一个连续的子数组,使得子数组中的元素之和最大。这个问题不仅在理论上有其重要性,而且在实际应用中也相当广泛,如在图像处理、信号分析等领域,最大子数组问题的解法可以用来检测图像的边缘或分析信号的峰谷。在形式上,最大子数组问题可以被定义为寻找数组 A[1...n] 的一个子数组,使得子数组 A[i...j] 的元素之和最大。数学上,这可以表达为找到两个下标 i 和 j,使得从 i 到 j 的子数组之和是所有可能子数组中最大的。
分治算法-求一个数组中的最大值和最小值
分治思想:将难以直接求解的大问题分解为k个相同的子问题;对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止;
python求最大连续子数组的和
主要介绍了python求最大连续子数组的和,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
算法实习:分治算法求n个数的数组中找出第二个最大元素
分治算法求n个数的数组中找出第二个最大元素


Java SE
