【问题标题】:How many random numbers can I get with .nextInt() from Random class in Java?使用 Java 中 Random 类的 .nextInt() 可以获得多少个随机数?
【发布时间】:2013-06-14 06:40:29
【问题描述】:

已解决:我在每次递归调用时都实例化一个新的 Random 对象。我把它作为一个静态变量放在 Quicksort 之外,现在它工作得很好。

我正在使用 Java 编写 Quicksort 以完成学校作业,但我被卡住了。我正在使用Random 类中的nextInt() 方法随机选择枢轴。这意味着我在每个递归步骤中都调用nextInt()。 我的快速排序在具有 20000 个元素的数组中完美地完成了这项工作。但是当我尝试对一个包含 40000 个元素的数组进行排序时,会出现这个 StackOverflowError

   java.lang.StackOverflowError: null (in java.util.Random)

我在 google 上搜索过这个错误,但对我没有任何帮助。我的猜测是我用完了随机整数,但我在 java 中太菜鸟了,我什至不买我自己的猜测。

这是我的代码(西班牙语是我的第一语言,对于蹩脚的英语和西班牙语代码感到抱歉)

public static void quicksort(String[] A, int min, int max){// llamar ord(A, 0, n-1);
    if(min >= max){
        return;
    }
    Random rand = new Random(); 
    int pivote = particionar(A, min, max, rand);
    quicksort(A, min, pivote-1);
    quicksort(A, pivote + 1, max);
    }

public static int particionar(String[] A, int min, int max, Random rand){    
    int menores = min + 1;
    int mayores = max;

    int pivote = rand.nextInt(max-min+1) + min;
    String pivotstr = A[pivote];
    //dejar pivote al principio
    String aux = A[min];
    A[min] = A[pivote];
    A[pivote] = aux;

    while(menores <= mayores){
        if(A[menores].compareTo(pivotstr) <= 0){
            menores++;
        }
        else{//intercambiar
            String aux2 = A[menores];
            A[menores] = A[mayores];
            A[mayores] = aux2;
            mayores--;
        }
    }
    //mover pivote donde corresponde
    String aux3 = A[min];
    A[min] = A[mayores];
    A[mayores] = aux3;

    return mayores;

}

【问题讨论】:

  • 我想说的是,在 StackOverflow 上实际发布任何内容之前,您可能应该阅读“StackOverflow 错误”的真正含义......

标签: java random pivot quicksort stack-overflow


【解决方案1】:

您的程序生成了太多级别的递归调用,导致堆栈内存不足。一种解决方案是在运行时增加堆栈大小,如here 所述。另一种是按照 lorenzo.marcon 的建议从递归转换为迭代。

Java 的默认随机数生成器是一个线性同余生成器,种子大小为 48 位,因此它的循环长度应为 2**48 量级。这意味着您不会用完随机整数,而是在那么多值之后重复序列。

堆栈溢出问题的一个重要原因是,每次递归调用都会实例化一个新的 Random 对象。你不会每次想喝水就挖一口新井,大多数人会挖一口井,然后再重新打水。同样,推荐的做法是实例化一个静态 Random 对象并重新访问它以获得更多值,除非您真的知道自己在做什么 - 您几乎从不想要多个 Random 对象。

【讨论】:

  • 谢谢,我会看看我能做些什么。但问题是 StackOverflowError 发生在 java.lang.Random 中,我不知道如何操作 Random 类来解决这个问题。此外,当我在没有随机枢轴但使用数组的第一个元素的情况下调用 Quicksort 时,ir 可以完美运行。
  • 使用不同的枢轴调用快速排序会导致完全不同的递归调用序列 - 你无法比较苹果和橘子。
  • 你是对的。谢谢:) 现在我解决了我的问题。我将变量 Random rand = new Random() 实例化出快速排序,现在它可以完美地处理超过 100.000 个元素的数组!
  • 我敢打赌,它的运行速度也会更快,即使在它已经工作的情况下也是如此。
  • 不,是一样的。另外,我在同一个数组中使用了 Heapsort(迭代),我的快速排序慢了 5 倍......确实出了点问题,或者我的计算机在递归时非常慢
【解决方案2】:

StackOverflowError 是递归运行过深时得到的结果。

解决方案:将其转换为迭代版本。 Way to go from recursion to iteration

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2015-06-01
    • 2020-06-14
    • 1970-01-01
    • 2019-02-20
    相关资源
    最近更新 更多