java 生成除某些值以外的随机数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14935997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 17:55:23  来源:igfitidea点击:

Generate random numbers except certain values

javarandomarraylist

提问by user2081119

I want to generate random numbers, but don't want them to be from excludearray. Here is my code.

我想生成随机数,但不希望它们来自exclude数组。这是我的代码。

public int generateRandom(int start, int end, ArrayList<Integer> exclude) {
    Random rand = new Random();
    int range = end - start +1 - exclude.size();
    int random = rand.nextInt(range) + 1;

    for(int i = 0; i < exclude.size(); i++) {
        if(exclude.get(i) > random) {
            return random;
        }
      random++;
    }

    return random;
}

I use this function in a while loop, and during each iteration I add a new value to exclude. Sometimes it returns numbers that belong to exclude. What's the problem?

我在 while 循环中使用此函数,并在每次迭代期间向exclude. 有时它返回属于exclude. 有什么问题?

采纳答案by Achintya Jha

if(!exclude.contains(random))
    return random;

Try this every time it will return the value that is not in exclude.

每次都会返回不在 exclude 中的值时尝试此操作。

回答by qben

I think there are some mistakes.

我认为有一些错误。

1) Range should be end - start + 1, because this is the range wanted.
2) If you really want random numbers (as "random" as possible on computers) then you shouldn't just get the next available number. Because in this case your random number will bear the characteristics of excluded numbers density/frequency.

1)范围应该是结束 - 开始+ 1,因为这是想要的范围。
2)如果您真的想要随机数(在计算机上尽可能“随机”),那么您不应该只获得下一个可用数字。因为在这种情况下,您的随机数将具有排除数密度/频率的特征。

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) {
    Random rand = new Random();
    int range = end - start + 1;
    int random;

    boolean success = false;
    while(!success) {
        random = rand.nextInt(range) + 1;
        for(Integer i: excludeRows) {
            if(i == random) {
                break;
            } else if (i > random) {
                success = true;
                break;
            }
        }
    }
    return random;
}

UPDATE

更新

With Achintya Jha's answer my code could be improved (but note there are some remarks as well):

有了 Achintya Jha 的回答,我的代码可以得到改进(但请注意也有一些评论):

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) {
    Random rand = new Random();
    int range = end - start + 1;

    int random = rand.nextInt(range) + 1;
    while(excludeRows.contains(random)) {
        random = rand.nextInt(range) + 1;
    }

    return random;
}

回答by BobTheBuilder

You check:

你检查:

for(int i = 0; i < exclude.size(); i++) {
    if(exclude.get(i) > random) {
        return random;
    }

and if only the first is larger, you'll return the value. Are you sure excludeis sorted?

如果只有第一个更大,您将返回该值。你确定exclude排序了?

You can use if(exclude.contains(random ))or the following algorithm:

您可以使用if(exclude.contains(random ))或 以下算法:

if (end-start)is a reasonable number, and you need almost all values you can create a list of all acceptable numbers and use random on this list size and choose the random value as an index. then remove the unwanted number from the list and get another random index.

如果(end-start)是一个合理的数字,并且您需要几乎所有的值,您可以创建一个所有可接受数字的列表,并在此列表大小上使用 random 并选择随机值作为索引。然后从列表中删除不需要的数字并获得另一个随机索引。

回答by edilon Junior

this worked for me:

这对我有用:

    public int randomInt(int start, int end, int... exception) {
        int result = -1;
        Random rand = new Random();
        int range = end - start + 1;
        boolean equals = true;

        while(equals) {
            result = rand.nextInt(range);
            boolean differentOfAll = true;
            for(int i : exception) {
                if(result==i) {
                    differentOfAll = false;
                    break;
                }
            }
            if(differentOfAll) {
                equals = false;
            }
        }

        return result;
    }

回答by Hongyang

Actually, we do not need to use contains(random)with a while loop.

实际上,我们不需要使用contains(random)while 循环。

To simplify the question, let's see what happens if we only have one excluding value. We can split the result to 2parts. Then the number of possible values is range-1. If the random number is less than the excluded value, just return it. Otherwise, we could add 1.

为了简化这个问题,让我们看看如果我们只有一个排除值会发生什么。我们可以将结果分成2几部分。那么可能值的数量是range-1。如果随机数小于排除值,则返回它。否则,我们可以添加1.

For multiple excluding values, We can split the result set into size+1parts, where sizemeans the number of excluding values. Then the number of possible values is range-size. Then we sort excluding values in ascending order. If random number is less than the excluding value minus i, then we just return the random number add i, where iis the index of the the excluding value.

对于多个排除值,我们可以将结果集拆分为多个size+1部分,其中size表示排除值的数量。那么可能值的数量是range-size。然后我们按升序对排除值进行排序。如果随机数小于排除值减去i,那么我们只返回随机数 add i,其中i是排除值的索引。

public int generateRandomNumberWithExcepts(int start, int end, List<Integer> excepts) {
    int size = excepts.size();
    int range = end - start + 1 - size;
    int randNum = random.nextInt(range) + start;
    excepts.sort(null); // sort excluding values in ascending order
    int i=0;
    for(int except : excepts) {
        if(randNum < except-i){
            return randNum + i;
        }
        i++;
    }
    return randNum + i;
}