【问题标题】:Generate random numbers except certain values生成除某些值之外的随机数
【发布时间】:2013-02-02 20:46:33
【问题描述】:

我想生成随机数,但不希望它们来自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 的数字。有什么问题?

【问题讨论】:

  • excludeRowsexclude 是同一个东西吗?
  • 是的,我忘记改名字了
  • 在此函数中,您不会将数字添加到excludeRows。所以在我的解决方案中,我也不这样做。我应该补充吗?
  • 将所有excludeRows重命名为exclude

标签: java random arraylist


【解决方案1】:

你检查:

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

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

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

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

【讨论】:

  • 我相信他依赖于排除已排序的事实。
【解决方案2】:

我认为有一些错误。

1) 范围应该是 end - start + 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;
}

【讨论】:

  • 非常感谢!很好的解决方案
【解决方案3】:
if(!exclude.contains(random))
    return random;

每次都试试这个,它会返回不在 exclude 中的值。

【讨论】:

  • @user2081119 我建议你看看我的解决方案。我认为有些评论会有所帮助。
【解决方案4】:

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

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

对于多个排除值,我们可以将结果集拆分为size+1部分,其中size表示排除值的个数。那么可能值的数量是range-size。然后我们按升序对排除值进行排序。如果随机数小于排除值减去i,那么我们只返回随机数加上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;
}

【讨论】:

    【解决方案5】:

    这对我有用:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 1970-01-01
      相关资源
      最近更新 更多