返回一个整数数组中最大子数组的和 (非环状 和环状)

题目要求:

输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。

要求数组从文件读取。
如果输入的数组很大, 并且有很多大的数字, 就会产生比较大的结果 (考虑一下数的溢出), 请保证你的程序能正常输出。
另外, 如果输入文件的参数有错误, 这个程序应该能正常退出, 并显示相应的错误信息。 任何输入错误都不能导致你的程序崩溃。

设计思路:

1. 首先理解题目,当时在课堂上老师给出题目的时候,我对于题目的理解有很大的偏差,结果对题目的解决造成很大困扰。

题目的意思是找到连续的子数组的和的最大值,这些子数组的意思是该数组所能构成的所有连续子数组,可以随意的任取。

举例子:

数组  {5,8,-6,7,10}

该数组的连续或单个子数组可以为  {5,8},{8,-6,7},{10}等 

而我却理解为把数组随机分解,然后找寻子数组的最大值

如分解为:

{5,8},{-6},{7,10};  

2.解决思路

解决非环状子数组最大值:

首先找到数组的第二个元素,将其与前一个元素相加进行比较,如果在该位置上的原有元素的值 比两个元素的值之和小,则将该位置的元素替代为两个元素的和,否则元素不变,

遍历该数组,执行该操作,如果前两个元素之和大于该元素,则替换,若后一个与现在值之和仍旧与前面一样,则这是可以构成一个至少三个连续元素的子数组。

如此便可以找到

例如:

{5 ,-6, 7, -5, 4} 

第一次(第二个开始): 后一个为负数,前一个为正数 相加必大于原来的值

{5,-6+5=-1,7,-5,4}

第二次:  前一个和后一个相加不符合条件 不执行操作

{5,-1,7,-5,4}

第三次:  符合条件 执行操作

{5,-1,7,-5+7=2,4}

第四次:  符号操作,执行操作

{5,-1,7,2,2+4=6}

如此,每一个位置都代表一种子数组的和,找寻最大值即可

第二种解决环状 参考 地址如下:

https://blog.csdn.net/weixin_34364071/article/details/93782011

首先要解决的是如何让收尾相加可以实现? 

在我的参考当中,是每次执行的时候都将首位元素调动到数组的最后位置。余下的就是防止在一个子数组当中让一个元素出现两次,造成多次相加。

对于该方法就是执行三次循环控制位置,避免元素的多次相加

3. 异常处理

创建一个继承自Exception 的自定义异常类,将除整数之外的其他情况排除,让文件读取时只能读取整数,当出现除整数之外的其他符号时,终止程序,并提升错误信息。

4. 目前刚刚完成程序,有点一叶障目的感觉,检查程序都会不自觉的按照程序设定能够运行的方式检验。不能发现错误,希望各位如果发现问题,请为我指正。

运行结果如下:

实现代码如下:

package Test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Scanner;



public class ReadShuZuMax {
    
        static Scanner sc=null;
        
        static int check(String c) throws MyException {
            if(!c.matches("^\\-?[0-9]+$")) {  //匹配所有的整数
                throw new MyException("数据异常,请重新录入!");
            }
            
            return Integer.valueOf(c);
        }
        
        public static void main(String[] args) throws Exception {
            
            BufferedReader bf=new BufferedReader(new FileReader(new File("C://Users//cuixingyu//Desktop//number.txt")));
            String textline="";
            String str="";
            
            while(((textline=bf.readLine())!=null)) {
                str+=textline;
            }
            System.out.println(str);
            
            String[] numbers=str.split(" ");
            int a[]=new int[numbers.length];
            int b[]=new int[numbers.length];
            for(int i=0;i<numbers.length;i++) {
                a[i]=check(numbers[i]);
                b[i]=check(numbers[i]);
            }
            
            int n=a.length;
            for(int i=1;i<n;i++) {    
                if(a[i]+a[i-1]>a[i]) {
                    a[i]=a[i]+a[i-1];
                }
            }
            
            int max=a[0];
            for(int i=1;i<n;i++) {     //找到最大的数组和
                max=Math.max(max, a[i]);
            }
            System.out.println("最大的子数组和(非环状):");
            System.out.println(max);
            
            int max1=0;
            for(int x=0;x<n;x++) {        //每次循环把第一个数移动到数组最后的位置,便于环形相加
                int w=b[0];
                for(int i=0;i<n-1;i++) {
                    b[i]=b[i+1];
                }
                b[n-1]=w;
                
                
                for(int y=0;y<n;y++) {       //最外层控制子数组的头
                    
                    for(int z=y;z<=n;z++) {   //中层控制子数组的尾
                        
                        int sum=0;
                        for(int u=y;u<z;u++) {   //内层循环从头加到尾
                            
                            sum=sum+b[u];
                            
                            if(max1<=sum) {   //把最大子数组的和赋值给max1
                                max1=sum;
                            }
                        }
                    }
                    
                }
                
                
            }
            System.out.println("最大的子数组和(环状):");
            System.out.println(max1);
            
        }
    

}

除此之外还有一个自定义的异常类

package Test;

public class MyException extends Exception{
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public MyException(String message) {
        super(message);
    }
}

猜你喜欢

转载自www.cnblogs.com/cxy0210/p/12368046.html