Java 如果我的int数组包含超过65535个元素,为什么最大和子数组会停止工作?

Java 如果我的int数组包含超过65535个元素,为什么最大和子数组会停止工作?,java,arrays,sorting,Java,Arrays,Sorting,我有一个程序,它根据用户输入生成一个数组(数组可以是降序、升序和两种类型的随机数组),然后使用暴力、分治和动态规划计算最大子数组和。它似乎工作得很好,最高可达65535。在那之后,每一个总数都是不同的,这是不应该发生的。35535是2乘以16减1的幂,所以我想知道我是否达到了极限。当我打印数组时,它似乎打印得很好,所以我认为问题不在于数组没有正确生成 这是主要课程: public class MainClass { public static void main(String[] args)

我有一个程序,它根据用户输入生成一个数组(数组可以是降序、升序和两种类型的随机数组),然后使用暴力、分治和动态规划计算最大子数组和。它似乎工作得很好,最高可达65535。在那之后,每一个总数都是不同的,这是不应该发生的。35535是2乘以16减1的幂,所以我想知道我是否达到了极限。当我打印数组时,它似乎打印得很好,所以我认为问题不在于数组没有正确生成

这是主要课程:

public class MainClass {

public static void main(String[] args) {

    int n = Integer.parseInt(args[1]);
    int[] maxsubarray1;
    maxsubarray1 = new Generator(n,args[3]).getArray();
    int[] maxsubarray2 = Arrays.copyOf(maxsubarray1,maxsubarray1.length);
    int[] maxsubarray3 = Arrays.copyOf(maxsubarray1,maxsubarray1.length); 

    System.out.println(Arrays.toString(maxsubarray1));
    solver solver = new solver();
    int solution;
    //if (args[5].equalsIgnoreCase("bruteforce")){
        long startTime = System.currentTimeMillis();
        solution = solver.bruteforce(maxsubarray1, n);
        System.out.println("__________BRUTE FORCE________\nThe sum of the array is "+solution);
        long endTime = System.currentTimeMillis() - startTime;
        System.out.println(endTime);
    //}
    //if (args[5].equalsIgnoreCase("divideconquer")){
        long startTime2 = System.currentTimeMillis();
        int solutiondivideconquer = solver.divideconquer(maxsubarray2, 0, n);
        System.out.println("__________DIVIDE AND CONQUERE________\nThe sum of the array is "+ solutiondivideconquer);
        long endTime2 = System.currentTimeMillis() - startTime2;
        System.out.println(endTime2);
    //}
    //if (args[5].equalsIgnoreCase("dynprog")){
        long startTime3 = System.currentTimeMillis();
        int solutiondynprog = solver.dynprog(maxsubarray3, n);
        System.out.println("__________DYNAMIC PROGRAMMING________\nThe sum of the array is "+ solutiondynprog);
        long endTime3 = System.currentTimeMillis() - startTime3;
        System.out.println(endTime3);
    //}
}

}
这是发电机代码:

import java.util.concurrent.ThreadLocalRandom;

public class Generator {

int size;
String type;
int[] generatedArray;

public Generator(int mysize, String mytype){
    size = mysize;
    type = mytype;
    generatedArray = new int[size];
}

public void ascending(){
    for(int i = 0; i < this.size; i++)
        generatedArray[i] = i+1;
}

public void descending(){
    for(int i = this.size -1; i >= 0; i--)
        generatedArray[i] = i+1;
}

public void random(){
    for(int i = 0; i <= this.size -1; i++)
        generatedArray[i] = ThreadLocalRandom.current().nextInt(-10*this.size, 10*this.size);
}

public void randominter(){
    for(int i = 0; i <= this.size -1; i++)
        if (i % 2 == 0)
            generatedArray[i] = ThreadLocalRandom.current().nextInt(1, 10*this.size);
        else if (i % 2 == 1)
            generatedArray[i] = ThreadLocalRandom.current().nextInt(-10*this.size, -1);
}

public int[] getArray(){
    if (type.equalsIgnoreCase("descending")){
        this.descending();
        return generatedArray;
    }
    if (type.equalsIgnoreCase("ascending")){
        this.ascending();
        return generatedArray;
    }
    if (type.equalsIgnoreCase("random")){
        this.random();
        return generatedArray;
    }
    if (type.equalsIgnoreCase("randominter")){
        this.randominter();
        return generatedArray;
    }
    return null;
}
}
import java.util.concurrent.ThreadLocalRandom;
公共类生成器{
整数大小;
字符串类型;
int[]生成阵列;
公共生成器(int mysize,String mytype){
大小=神秘化;
类型=mytype;
GenerateArray=新整数[大小];
}
公共空间(英文){
for(int i=0;i=0;i--)
生成阵列[i]=i+1;
}
公屋{

对于(int i=0;ii是错误的,如果
Array[i]=i+1
,则可能是溢出错误,因为总和是
length*(min+max)/2
>Integer.max\u VALUE

我复制了您的代码,将所有int更改为long,并且工作正常。还更改了
n=Integer.parseInt(args[0])
,而不是
n=Integer.parseInt(args[1])

然后我调用了我的程序,比如
program\u name 1000 random

我检查了excel,只有bruteforce出错。我已将
Integer.MIN_值
更改为
Long.MIN_值
,并将
int sum
更改为
Long sum

Main.java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;


public class Main {

    public static void main(String[] args) {

        int n = Integer.parseInt(args[0]);
        long[] maxsubarray1;
        maxsubarray1 = new Generator(n, args[1]).getArray();
        long[] maxsubarray2 = Arrays.copyOf(maxsubarray1, maxsubarray1.length);
        long[] maxsubarray3 = Arrays.copyOf(maxsubarray1, maxsubarray1.length);

        System.out.println(Arrays.toString(maxsubarray1));
        solver solver = new solver();
        long solution;
        //if (args[5].equalsIgnoreCase("bruteforce")){
        long startTime = System.currentTimeMillis();
        solution = solver.bruteforce(maxsubarray1, n);
        System.out.println("__________BRUTE FORCE________\nThe sum of the array is " + solution);
        long endTime = System.currentTimeMillis() - startTime;
        System.out.println(endTime);
        //}
        //if (args[5].equalsIgnoreCase("divideconquer")){
        long startTime2 = System.currentTimeMillis();
        long solutiondivideconquer = solver.divideconquer(maxsubarray2, 0, n);
        System.out.println("__________DIVIDE AND CONQUERE________\nThe sum of the array is " + solutiondivideconquer);
        long endTime2 = System.currentTimeMillis() - startTime2;
        System.out.println(endTime2);
        //}
        //if (args[5].equalsIgnoreCase("dynprog")){
        long startTime3 = System.currentTimeMillis();
        long solutiondynprog = solver.dynprog(maxsubarray3, n);
        System.out.println("__________DYNAMIC PROGRAMMING________\nThe sum of the array is " + solutiondynprog);
        long endTime3 = System.currentTimeMillis() - startTime3;
        System.out.println(endTime3);
        //}
    }

}
solver.java

public class solver {


    //brute force algorithm with complexity O(n^2)
    long bruteforce(long array[], int n){

        long max = Long.MIN_VALUE;
        //We go throght all the elements of the list and we try all the
        //posible combinations with all the other elements
        for (int i = 0; i < n; i++){
            long sum = 0;
            for (int j = i; j < n ; j++){
                //we add the an element in the sum
                sum += array[j];
                //we check if the sum with the new element is greater that the value we had before
                if(sum > max){
                    //if it's greater, it becomes the new value
                    max = sum;
                }
            }
        }
        //we return the maximum value we have found
        return max;
    }

    //to implement the divide and conquer algorithm we have to take into account the
// maximum subarray can have elements in the right subarray and in the left subarray
    long maxCrossingSum(long array[], long l, long m, long h){
        long sum = 0;
        long left_sum = Integer.MIN_VALUE;
        //Has the elements on the left part of the arrray
        for ( int i = (int)m; i >= l; i--){
            sum = sum + array[i];
            if( sum > left_sum ){
                left_sum = sum;
            }
        }

        sum = 0;
        long right_sum = 0;
        //Has the elements in the right part of the array
        for ( int j = (int)m+1; j <= h; j++){
            sum = sum + array [j];
            if (sum > right_sum){
                right_sum = sum;
            }
        }
        //returns the sun of the elements on the left and the right of the array
        return left_sum + right_sum;
    }

    //returns the sum of the maximum subarray
    long maxSubarraySum(long array[], long l, long h){

        if(l == h)
            return array[1];

        long m = (l + h)/2;
        //checks which is the maximum between left and right
        long maxBetweenLeftRight = max(maxSubarraySum(array, l, m), maxSubarraySum(array, m+1,h));
        long crossing = maxCrossingSum(array, l, m,h-1);
        //retrns the maximum between one of the sides and the crossing sum
        return max(maxBetweenLeftRight, crossing);

    }
    //divide and conquere algorithm with complexity O(nlogn)
    //only made to make it more understandable from the main
//can call maxSubarraySum and it would be the same
    long divideconquer (long array[], int l, int h){

        return maxSubarraySum(array, l, h);
    }

    //dynamic programming algorithm with complexity O(n)
    long dynprog(long array[], int n){
        long a = array[0];
        long b = array[0];
        //for all the elements checks if the sum was better until the
        //step before or adding the element
        for (int i = 1 ; i < n; i++){
            a= max (a+ array[i], array[i]);
            b= max(b, a);
        }
        return b;
    }

    private long max(long a, long b) {
        if (a > b ) return a;
        else return b;
    }
}
公共类求解器{
//复杂度为O(n^2)的蛮力算法
长蛮力(长数组[],int n){
长最大值=长最小值;
//我们浏览了列表中的所有元素,并尝试了所有
//所有其他元素的可能组合
对于(int i=0;i最大值){
//如果它更大,它将成为新值
最大值=总和;
}
}
}
//我们返回找到的最大值
返回最大值;
}
//为了实现分治算法,我们必须考虑
//最大子阵列可以在右侧子阵列和左侧子阵列中包含元素
长最大交叉数(长数组[],长l,长m,长h){
长和=0;
长左_和=Integer.MIN_值;
//元素位于阵列的左侧
对于(int i=(int)m;i>=l;i--){
总和=总和+数组[i];
如果(总和>左总和){
左和=和;
}
}
总和=0;
长右_和=0;
//元素位于数组的右侧
对于(int j=(int)m+1;j右和){
右和=和;
}
}
//返回数组左侧和右侧元素的太阳
返回左求和+右求和;
}
//返回最大子数组的和
长最大子阵列和(长阵列[],长l,长h){
如果(l==h)
返回数组[1];
长m=(l+h)/2;
//检查左右之间的最大值
long maxBetweenLeftRight=max(MaxSubraySum(数组,l,m),MaxSubraySum(数组,m+1,h));
长交叉=最大交叉(阵列,l,m,h-1);
//重新计算其中一条边与交叉总和之间的最大值
返回最大值(maxBetweenLeftRight,交叉);
}
//复杂度为O(nlogn)的分而治之算法
//只是为了让它从总体上更容易理解
//可以调用MaxSubraySum,它将是相同的
长除法征服(长数组[],整数l,整数h){
返回最大子数组和(数组,l,h);
}
//复杂度为O(n)的动态规划算法
长dynprog(长数组[],int n){
长a=数组[0];
长b=数组[0];
//对于所有元素,检查总和是否更好,直到
//在添加元素之前或之后执行步骤
对于(int i=1;ib)返回a;
否则返回b;
}
}
Generator.java

import java.util.concurrent.ThreadLocalRandom;

public class Generator {

    int size;
    String type;
    long[] generatedArray;

    public Generator(int mysize, String mytype) {
        size = mysize;
        type = mytype;
        generatedArray = new long[size];
    }

    public void ascending() {
        for (int i = 0; i < this.size; i++)
            generatedArray[i] = i + 1;
    }

    public void descending() {
        for (int i = this.size - 1; i >= 0; i--)
            generatedArray[i] = i + 1;
    }

    public void random() {
        for (int i = 0; i <= this.size - 1; i++)
            generatedArray[i] = ThreadLocalRandom.current().nextInt(-10 * this.size, 10 * this.size);
    }

    public void randominter() {
        for (int i = 0; i <= this.size - 1; i++)
            if (i % 2 == 0)
                generatedArray[i] = ThreadLocalRandom.current().nextInt(1, 10 * this.size);
            else if (i % 2 == 1)
                generatedArray[i] = ThreadLocalRandom.current().nextInt(-10 * this.size, -1);
    }

    public long[] getArray() {
        if (type.equalsIgnoreCase("descending")) {
            this.descending();
            return generatedArray;
        }
        if (type.equalsIgnoreCase("ascending")) {
            this.ascending();
            return generatedArray;
        }
        if (type.equalsIgnoreCase("random")) {
            this.random();
            return generatedArray;
        }
        if (type.equalsIgnoreCase("randominter")) {
            this.randominter();
            return generatedArray;
        }
        return null;
    }
}
import java.util.concurrent.ThreadLocalRandom;
公共类生成器{
整数大小;
字符串类型;
长[]生成阵列;
公共生成器(int mysize,String mytype){
大小=神秘化;
类型=mytype;
GenerateArray=新长[尺寸];
}
公共空间(英文){
for(int i=0;i=0;i--)
生成阵列[i]=i+1;
}
公屋{

对于(int i=0;i),它只是停止,没有错误消息、stacktrace或任何东西?65535是
无符号short
的最大值。不,它打印所有内容,只是总和不一致,而不管方法是什么,所有三个总和都应该相同。第二个if in
if(i%2==0)else if(i%2==1)
是无用的,因为一旦它进入else部分,
i%2
将始终是1,所以只需
else
就足够了问题在于
n
大于65535,或者数组的值更大
import java.util.concurrent.ThreadLocalRandom;

public class Generator {

    int size;
    String type;
    long[] generatedArray;

    public Generator(int mysize, String mytype) {
        size = mysize;
        type = mytype;
        generatedArray = new long[size];
    }

    public void ascending() {
        for (int i = 0; i < this.size; i++)
            generatedArray[i] = i + 1;
    }

    public void descending() {
        for (int i = this.size - 1; i >= 0; i--)
            generatedArray[i] = i + 1;
    }

    public void random() {
        for (int i = 0; i <= this.size - 1; i++)
            generatedArray[i] = ThreadLocalRandom.current().nextInt(-10 * this.size, 10 * this.size);
    }

    public void randominter() {
        for (int i = 0; i <= this.size - 1; i++)
            if (i % 2 == 0)
                generatedArray[i] = ThreadLocalRandom.current().nextInt(1, 10 * this.size);
            else if (i % 2 == 1)
                generatedArray[i] = ThreadLocalRandom.current().nextInt(-10 * this.size, -1);
    }

    public long[] getArray() {
        if (type.equalsIgnoreCase("descending")) {
            this.descending();
            return generatedArray;
        }
        if (type.equalsIgnoreCase("ascending")) {
            this.ascending();
            return generatedArray;
        }
        if (type.equalsIgnoreCase("random")) {
            this.random();
            return generatedArray;
        }
        if (type.equalsIgnoreCase("randominter")) {
            this.randominter();
            return generatedArray;
        }
        return null;
    }
}