Java生成指定位数的随机整数

10

今天我遇到了这个问题,我相信有一种优雅的解决方案我没有考虑到。

假设我想在Java中生成一个指定位数的随机整数(或长整型),其中这个位数可以改变。

即,在方法中传入数字位数,返回一个具有指定位数的随机数。

例如:N = 3,生成介于100-999之间的随机数; N = 4,生成介于1000-9999之间的随机数。

private long generateRandomNumber(int n){

/*Generate a random number with n number of digits*/

}

我迄今为止的尝试(这个方法可行,但看起来有点凌乱)

private long generateRandomNumber(int n){

    String randomNumString = "";

    Random r = new Random();

    //Generate the first digit from 1-9
    randomNumString += (r.nextInt(9) + 1);

    //Generate the remaining digits between 0-9
    for(int x = 1; x < n; x++){
        randomNumString += r.nextInt(9);
    }

    //Parse and return
    return Long.parseLong(randomNumString);

}

有比这个更好/更有效的解决方案吗?

*在指定范围内生成随机数有很多解决方案,但我更想知道生成给定位数的随机数的最佳方法,以及使解决方案足够强大,可以处理任意数量的位数。

我不想传递最小值和最大值,而只是需要指定位数。


2
我喜欢你的方法,因为它不会受到长长度的限制,除非你将其转换为长整型。 - Elye
@aetheria 更新了内容,说明它不是重复的。 - Tony Scialo
@aetheria,你能解释一下为什么这是一个重复的问题吗?这是一个完全不同于你所提到的那个问题。 - Tony Scialo
4个回答

15
private long generateRandomNumber(int n) {
    long min = (long) Math.pow(10, n - 1);
    return ThreadLocalRandom.current().nextLong(min, min * 10);
}

nextLong会生成包括下限但不包括上限的随机数。例如,使用参数 (1_000, 10_000) 将生成1000到9999之间的数字。 遗憾的是,旧版的Random没有这些新特性。但基本上没有理由继续使用它。


啊,我错过了这个方法,尽管它使用了相同的边界检查思路:while (r < origin || r >= bound) - Kedar Mhaswade
我之前不知道ThreadLocalRandom。你建议一般情况下使用它来生成随机数吗? - Tony Scialo
@TonyScialo 是的。https://dev59.com/kGAg5IYBdhLWcg3wm7_7(除非您需要安全随机数) - zapl

5
public static int randomInt(int digits) {
    int minimum = (int) Math.pow(10, digits - 1); // minimum value with 2 digits is 10 (10^1)
    int maximum = (int) Math.pow(10, digits) - 1; // maximum value with 2 digits is 99 (10^2 - 1)
    Random random = new Random();
    return minimum + random.nextInt((maximum - minimum) + 1);
}

2
您可以简单地忽略不在所需范围内的数字。这样,您修改后的伪随机数生成器就保证以随机均匀的方式生成给定范围内的数字:
public class RandomOfDigits {
    public static void main(String[] args) {
        int nd = Integer.parseInt(args[0]);
        int loIn = (int) Math.pow(10, nd-1);
        int hiEx = (int) Math.pow(10, nd);
        Random r = new Random();
        int x;
        do {
            x = r.nextInt(hiEx);
        } while (x < loIn);
        System.out.println(x);
    }
}

“int x = loIn + r.nextInt(hiEx - loIn)” 的表达更加恰当。 - andrucz
为什么会这样呢?我尝试了一百万次迭代,但我的伪随机数生成器好像总是偏向于平均值。也许我应该再试试... - Kedar Mhaswade

0
这是我自然而然编写此类方法的方式:
private long generateRandomNumber(int n){
    double tenToN = Math.pow(10, n),
           tenToNMinus1 = Math.pow(10, n-1);
    long randNum = (long) (Math.random() * (tenToN - tenToNMinus1) + tenToNMinus1);
    return randNum;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接