生成除特定值之外的随机数

时间:2013-02-18 12:11:02

标签: java random arraylist

我想生成随机数,但不希望它们来自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;
}

我在while循环中使用此函数,并且在每次迭代期间,我向exclude添加一个新值。 有时它会返回属于exclude的数字。有什么问题?

5 个答案:

答案 0 :(得分:8)

我认为有一些错误。

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;
}

<强>更新

有了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;
}

答案 1 :(得分:5)

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

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

答案 2 :(得分:2)

你检查:

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

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

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

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

答案 3 :(得分:0)

这对我有用:

    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;
    }

答案 4 :(得分:-1)

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

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

对于多个排除值,我们可以将结果集拆分为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;
}