【问题标题】:Is it possible to change range of random numbers?是否可以更改随机数的范围?
【发布时间】:2017-09-19 23:47:50
【问题描述】:

我有一个在 0-20 范围内生成的非重复随机数数组

int[] numbers = {6,14,11,18,13};

现在,我想将这些数字转换为 0-10 范围内的数字,并且我希望结果也是不重复的。

有可能吗?

任何形式的建议都将不胜感激。

【问题讨论】:

  • 除以 2。
  • 我之前也想过,但是对于像 10 和 11 这样的数字它给出了相同的结果
  • 要么按照@Turing85 的建议将每个数字除以 2,要么只删除所有大于 10 的数字。任何一种方式都可以。
  • @Sagar 向我们展示你使用的代码,这对我来说听起来不对。
  • 您所要求的通常是不可能的。如果可能的话,您可以将通用方法应用于由 12 个这些随机数组成的数组,从而为您提供 0 到 10 之间的 12 个不同数字 - 矛盾。

标签: java arrays random


【解决方案1】:

如果随机生成的数字大于 10,你可以减去 10。我知道这不是一个合适的解决方案,但它肯定对你有用。

【讨论】:

    【解决方案2】:

    将它们除以 2 是一个很好的解决方案,因为您有相同大小的输入并且保持一致性:

    对于 [0;10[ 中的每个数字 x 的每个数字,它可以来自 [0;20[ 中的两个数字:2*x 和 2*x+1。

    对于像 10 和 11 这样的数字,它会给你相同的结果,但谁在乎呢?

    【讨论】:

    • 我需要数组中不重复的数字,这就是原因
    • 那么阐述的问题缺少一些细节。如果您需要不重复的数字,那么您的输入中最多必须有 10 个不同的值。如果你有更多,你就做不到。
    • 数字 0-9 在结果中出现的频率是 10 的两倍。
    • 我只需要 5 个值并且也是唯一的。生成的数字范围是 0-20,我想在 0-10 范围内转换这些数字。
    • @Sagar,您的问题在每条评论中都在发生变化......您应该在拒绝回答之前适当地了解它
    【解决方案3】:

    以下是我想出的三种方法:

    // divide by 2
    Arrays.stream(numbers).map(x -> x / 2);
    // subtract 10 from everything that's > 10
    Arrays.stream(numbers).map(x -> x > 10 ? x - 10 : x);
    // remove every number that's > 10
    Arrays.stream(numbers).filter(x -> x < 10);
    

    现在我知道您不想重复数字,您应该调用distinct 删除所有重复的数字。

    【讨论】:

    • 赞成负 10 选项,这应该适用于 AFAIK。
    【解决方案4】:

    如果你使用的是Java8,你可以使用下面的代码来生成唯一的随机数:

    int[] rand = new Random().ints(0, 11).distinct().limit(5).toArray();
    

    此代码生成 5 个唯一的随机数,范围从 0 到 10。

    【讨论】:

      【解决方案5】:

      范围 0-20 包含 21 个数字,0-10 包含 11 个数字。因此,唯一导致数字均匀分布的解决方案是从原始集合中仅取 0-10 范围内的数字,并丢弃 11-20 范围内的数字。

      【讨论】:

      • 不,我不同意。如果0-10 是均匀分布的,那为什么0-20 也不是均匀分布的?
      • @TimBiegeleisen 问题是,如果您在映射到 0-10 时尝试使用从 0-20 的所有数字,则 11 个结果之一的命中率将低于其他结果。
      • 好吧,你可能是对的。 OP 应该清楚地告诉我们范围以及每个端点是打开还是关闭。
      【解决方案6】:

      您可以使用 if 条件在增强的 for 循环中迭代数组。您已经有了非重复值,因为您从数字数组中获取值。您可以使用 arraylist 或任何其他数据结构来存储小于 10 的随机数。

      ArrayList<Integer> numberList = new ArrayList<>();
      for(int number:numbers){
          if(number<10){
              numberList.add(number);
          }
      }
      

      【讨论】:

        【解决方案7】:

        一种可能的解决方案是使用具有双值的辅助数组。

        接下来是算法。

        1. 从原始数组创建一个包含双精度值的数组,并将值除以 2。
        2. 在新的双精度数组中找到最大值。
        3. 缩放新双精度数组中的所有值。这应该通过将所有值乘以一个系数来完成。系数为coefficient = 10 / max
        4. 将新的双精度数组转换为整数值。一种可能的策略是舍入双精度值。

        备注

        • 此解决方案可能存在一些“错误”,并且不适用于所有随机数组合。在这种情况下,应该改进双精度值到整数的转换。
        • 如果原始数组包含超过 10 个值,则无法将该数组映射到新数组。

        这是它的代码。

        public static void main(String[] args) {
            int[] numbers = { 6, 14, 11, 18, 13 };
        
            // crate a new array with double values
            double[] newNumbers = new double[numbers.length];
            for (int i = 0; i < numbers.length; i++) {
                newNumbers[i] = (double) numbers[i] / 2;
            }
        
            // get coefficient
            double max = maxValue(newNumbers);
            double coefficient = 10 / max;
        
            // scale numbers
            for (int i = 0; i < newNumbers.length; i++) {
                newNumbers[i] = newNumbers[i] * coefficient;
            }
            int[] newIntNumbers = new int[newNumbers.length];
            for (int i = 0; i < newNumbers.length; i++) {
                newIntNumbers[i] = (int) Math.round(newNumbers[i]);
            }
        
            System.out.println(Arrays.toString(newNumbers));
            System.out.println();
            System.out.println(Arrays.toString(newIntNumbers));
        }
        
        private static double maxValue(double[] array) {
            double max = Double.MIN_VALUE;
            for (double num : array) {
                max = Math.max(max, num);
            }
            return max;
        }
        

        【讨论】:

        • 适用于大多数情况,但正如你所说的那样有一些错误
        • 我没有深入研究从双精度到整数的转换。如果您愿意,可以尝试改进这行代码newIntNumbers[i] = (int) Math.round(newNumbers[i]);。那应该可以解决那些“错误”。
        • 是的,一些时间值重复了接近数字,如 10、11 等
        • 您可以尝试缩放到最小值而不是最大值。
        猜你喜欢
        • 1970-01-01
        • 2020-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-16
        相关资源
        最近更新 更多