【问题标题】:Java: Random number in fixed range excluding specified numberJava:不包括指定数字的固定范围内的随机数
【发布时间】:2015-05-31 14:57:05
【问题描述】:

在我的 (Java Android) 游戏中,我在随机位置生成硬币。

硬币可以出现在屏幕上水平的 6 个位置之一(每个水平级别最多 2 个)。

我所做的是为第一枚硬币创建一个介于 0 和 5 之间的随机数,然后我想生成另一个随机数排除第一枚硬币的位置。

因此,例如,硬币 1 在 0 到 5 之间的随机位置生成 - 假设是 4。

那么下一个硬币需要能够在0-3或5之间选择。(基本上是0-5不包括4)。

我已经设法做到了,但它不是很优雅,我确信必须有更好/更清洁的方法来实现这一点,但是,它逃脱了我。

下面代码中的 random(int number) 方法只返回一个从 0 到 number-1 的随机 int(使用 nextInt),而 randomBool() 只返回一个随机布尔值

另外,请记住,如果它产生的随机数等于我们试图避免的随机数,我不想使用任何不断重新生成随机数的技术。

代码

    //Return a random number between 0 and 5 excluding the specified number
    private int getRandomExcluding(int excludedNumber){

        //If previous position was 0 then generate a number between 1 and 5
        if (excludedNumber==0){
                return random(5)+1;
        }
        //If position was 5, then generate and return number from 0-4
        else if (excludedNumber==5){
                return random(5);
        }

        //If number isn't 0 or 5 (then it is in range of 1-4 use a random bool to determine
        // if we are going to get a number less than or greater than the number we are excluding

        //True - get number lower than excluded number
        else if(randomBool()){

            //Excluded number is 1
            if (excludedNumber==1){
                return 0;  //Only posibility
            }

            //Excluded number is > 1
            else {
                //Return a random number between 0 (inclusive) and the excluded number (exclusive)
                return random(excludedNumber);
                }

        //False - get number higher than the excluded number (between exludedNumber+1 (inclusive) and 6(exlusive))
        else {
                return random(6-(excludedNumber+1))+(excludedNumber+1);
        }
    }

【问题讨论】:

  • 使用一组可能的值,在选择时删除每个值。
  • 一种方法是用有效值填充一个列表,打乱它,然后返回前两个元素。
  • 我喜欢这个想法,我猜这将是一个长度为 5 的数组的形式,并且可能会打开 excludeNumber,这将使用相关值填充数组(因此,案例 0将填充 1,2,3,4 和 5,案例 1 填充 0,2,3,4 和 5 等),然后只生成一个介于 0 和 5 之间的随机数并转到该数组的索引以检索价值?!如果有比我的解释更好的方式将其付诸实践,也许您可​​以将您的想法作为答案发布?!谢谢!!!! ——

标签: java random int


【解决方案1】:

您可以填充一个列表并随机播放它:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Collections.shuffle(numbers);
int coin1 = numbers.get(0);
int coin2 = numbers.get(1);

【讨论】:

【解决方案2】:

试试这个解决方案:

private int getRandomExcluding(int excludedNumber){
    int num = random(5);
    return num >= excludedNumber ? num+1 : num;
}

它只是生成从 0 到 4 的随机数,如果它大于或等于排除的数字,它会加一。这样所有五个可能的数字都是均匀分布的(如果您的 RNG 产生均匀分布的数字)。

【讨论】:

  • ... 这在多个方面被破坏了;它可以超出范围,并且不是迭代的。更好的解决方案是使用一组可能的值。
  • 超出哪个范围?为什么它应该是迭代的?问题中没有关于 iterativeness 的内容。
  • 我错过了“只有两个数字”的部分,虽然我害怕幻数。我认为该解决方案实际上有效,因为您只生成 0-4,所以很抱歉。不过,我认为这并不是特别随机,因为您总是递增。我认为规范的解决方案(洗牌或集合)仍然更好,更适合通用性。
【解决方案3】:

解决方案:(如果您喜欢这种类型的输入,您可以将List&lt;Integer&gt; excludes 更改为int... excludes

    /**
     * Get a random number between a range and exclude some numbers
     *
     * @param start start number
     * @param end end number
     * @param excludes list of numbers to be excluded
     * @return value between {@code start} (inclusive) and {@code end} (inclusive)
     */
    private int getRandomWithExclusion(int start, int end, List<Integer> excludes) {
        Collections.sort(excludes); // this method only works with sorted excludes

        int random = start + new Random().nextInt(end - start + 1 - excludes.size());
        for (int exclude : excludes) {
            if (random < exclude) {
                break;
            }
            random++;
        }
        return random;
    }

【讨论】:

    猜你喜欢
    • 2014-10-23
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多