【问题标题】:Generate random integer in range multiple of another integer in Java在Java中生成另一个整数的倍数范围内的随机整数
【发布时间】:2019-05-02 00:41:13
【问题描述】:

我正在努力完成实用程序方法以生成 2 个整数范围内的数字,该数字也是另一个整数的乘数。

例如:

public static void main(String[] args) {
    getIntegerInRangeMultipleOf(100, 1000, 444);
} 

应该产生 444888。没有别的了。

我想出了这个解决方案:

public static int getIntegerInRangeMultipleOf(int minInclusive, int maxInclusive, int multiplier) {
    return Math.toIntExact(Math.round((Math.random() * (maxInclusive - minInclusive) + minInclusive) / multiplier) * multiplier);
}

但对于上面的示例,除了 444888 之外,有时它还会产生 0(零)。

请建议如何修复该功能。

【问题讨论】:

  • 您在 900 的范围内构建了一个阶跃函数,将结果四舍五入到最接近的 444。444888 的可能性是否相同,或者是否存在某种加权,因为范围是更大?
  • 根本没有暗示权重。 444 和 888 的可能性应该相等。

标签: java algorithm random integer


【解决方案1】:

我认为你可以稍微简化一下数学。让我们创建一个最小乘数和一个最大乘数。

如果minInclusive小于(或等于)multiplier,那么我们知道我们可以将minMultiplier设置为1。否则,它等于大于minInclusivemultiplier 的下一个倍数除以multiplier

maxInclusive 必须大于(或等于)multiplier,因此我们可以将maxMultiplier 设置为maxInclusive / multiplier

然后,我们只需将multiplier 乘以minMultipliermaxMultiplier 之间的随机数,两端都包括:

public static int getIntegerInRangeMultipleOf(int minInclusive, int maxInclusive, int multiplier) {
    int minMultiplier = minInclusive <= multiplier ? 1 : (int) Math.ceil((double) minInclusive / multiplier);
    int maxMultiplier = maxInclusive / multiplier;
    return multiplier * ThreadLocalRandom.current().nextInt(minMultiplier, maxMultiplier + 1);
}

我已经用许多不同范围的正数对此进行了测试,它似乎工作得很好。

【讨论】:

  • 完美运行!谢谢。虽然我发现了 2 个问题:1)它不尊重负数:getIntegerInRangeMultipleOf(-500, 500, 500) 不会产生 -500 作为有效值; 2) 如果maxInclusive 小于multiplier 并且multiplier0(零),则抛出异常。我个人对这两个问题都很好,也许只是为了使答案完整,你可以增强它。再次感谢!
【解决方案2】:

Math.random() 返回0.0 时,它返回0。可以通过以下测试简单找到

public static int getIntegerInRangeMultipleOf(int minInclusive, int maxInclusive, int multiplier) {
        double v =0.0 * (maxInclusive - minInclusive) + minInclusive;
        System.out.println("v = " + v);
        return Math.toIntExact(Math.round(v / multiplier) * multiplier);
    }

@Test
public void test () {
    int t =  getIntegerInRangeMultipleOf(100, 1000, 444);
    System.out.println(t);
}

【讨论】:

    【解决方案3】:

    如果我们添加一个 contiditon 来选择添加到 Math.random() * (maxInclusive - minInclusive) ,我们可以消除 0 的情况。

    public static int getIntegerInRangeMultipleOf(int minInclusive, int maxInclusive, int multiplier) {
        return Math.toIntExact(Math.round((Math.random() * (maxInclusive - minInclusive) + ( minInclusive < multiplier ? multiplier : minInclusive) ) / multiplier) * multiplier);
    }
    

    【讨论】:

    • 问题中的示例使用此代码产生 1332 :(
    【解决方案4】:

    不知道如何取出演员表(int),但似乎有效

    public static int getIntegerInRangeMultipleOf(int minInclusive,
                                                  int maxInclusive,
                                                  int multiplier) {
        double random =
                ((Math.random()*(1d - 0.1) + 0.1) * (maxInclusive - minInclusive) + minInclusive) / multiplier;
        if(random < 1) {
            return multiplier;
        } else {
            return (int) Math.floor(random) * multiplier;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-11
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多