【问题标题】:Math.random repeating itselfMath.random 重复自己
【发布时间】:2016-02-19 06:40:57
【问题描述】:

到目前为止,我的代码几乎可以正常工作。说明在方法之上。我遇到的唯一问题是Math.random(); 在多次调用时会重复。我想知道是否有防止Math.random(); 重复的解决方案;

/**
 * Apply an "efficient selection shuffle" to the argument.
 * The selection shuffle algorithm conceptually maintains two sequences
 * of cards: the selected cards (initially empty) and the not-yet-selected
 * cards (initially the entire deck). It repeatedly does the following until
 * all cards have been selected: randomly remove a card from those not yet
 * selected and add it to the selected cards.
 * An efficient version of this algorithm makes use of arrays to avoid
 * searching for an as-yet-unselected card.
 * @param values is an array of integers simulating cards to be shuffled.   
 */
public static void selectionShuffle(int[] values) {
    ArrayList<Integer> temp=new ArrayList<Integer>();
    int size=52;
    for(int j=0;j<size;j++){
        /*int random=(int)(Math.random()*51);
        temp.add(random);
        values[j]=temp.get(j);*/
        int random=(int)(Math.random()*51);
        temp.add(values[random]);
        values[j]=temp.get(j);
    }
}

【问题讨论】:

  • Math.random() 将运行 52 次,因为您已将其置于循环中。每次调用该方法时它都会运行。这是你的问题吗?
  • 或者你的意思是Math.random()返回的值?
  • 我建议你尝试在你的方法上面实现注释。您当前的代码没有这样做。 (我还建议使用 Random 类而不是 Math.random。)
  • 您可以在循环外使用 create Random random = new Random();,然后在循环内调用 random.nextDouble()
  • @PragnaniKinnera,因为values 是一个原始数组,所以这不起作用。如果你有番石榴,你可以Collections.shuffle(Ints.asList(values))

标签: java math random


【解决方案1】:

如果您希望整数 0-51 以随机顺序不重复:

  • 按顺序将这些数字添加到列表中
  • 在该名单上致电Collections.shuffle

根据birthday paradox,简单地使用(int) (52 * Math.random()) 51 次几乎可以保证某些数字会重复(当然,有些数字会丢失)。

【讨论】:

    【解决方案2】:

    据我所知,您认为 Math.random 是“重复的”,因为您总是选择 0 到 51 之间的新数字添加到您的 values 数组中。在您有机会选择这些数字之前,您正在覆盖 values 数组的早期部分。

    考虑说明中概述的过程。如果您每次迭代都从初始数组中选择一次,并将这些选择移动到新的temp 数组中,那么values 不应该每次都变小吗?也许你并不总是想要一个 0-51 的随机数。

    并且忽略所有告诉你不同方式进行洗牌的人。显然,您正在尝试实现为编码实践给出的算法。

    【讨论】:

      【解决方案3】:

      不确定您的问题是什么,但请尝试改用 java.util.Random。

      public static void selectionShuffle(int[] values)
      {
          ArrayList<Integer> temp=new ArrayList<Integer>();
          Random randomGenerator = new Random();
      
          int size=52;
      
          for(int j=0;j<size;j++){
              // If you wan to generate a random number up to a maximum value,
              // use randomGenerator.nextInt(maximum) instead
              int random = randomGenerator.nextInt() * 51;
              temp.add(values[random]);
              values[j]=temp.get(j);
          }
      }
      

      【讨论】:

        【解决方案4】:

        当数字是随机的时,每个数字都有相同的机会出现,无论之前发生了什么。这意味着随机数必须能够自我重复,否则它们不再是真正的随机数。

        如果您希望一组数字、卡片、歌曲以随机顺序出现而不重复,这称为随机播放。注意:最后一个数字、卡片或歌曲根本不会是随机的,因为它将是唯一剩下的一个。

        使用随机序列,您甚至可以得到多次出现的相同数字。

        http://vanillajava.blogspot.co.uk/2011/10/randomly-no-so-random.html

        Random random = new Random(441287210);
        for (int i = 0; i < 10; i++)
            System.out.print(random.nextInt(10)+" ");
        

        打印

        1 1 1 1 1 1 1 1 1 1
        

        Random random = new Random(-6732303926L);
        for(int i = 0; i < 10; i++)
            System.out.print(random.nextInt(10)+" ");
        

        打印

        0 1 2 3 4 5 6 7 8 9
        

        【讨论】:

          【解决方案5】:

          据我了解,您不希望 Math.random() 多次返回一个数字。如果这是问题所在,我们将允许Math.random() 返回它喜欢的任何内容,但我们将只使用非重复的数字。

          试试这个:

          public static void selectionShuffle(int[] values) {
              ArrayList<Integer> temp=new ArrayList<Integer>();
              int size=52;
              Integer a[]=new Integer[size];
              for(int j=0;j<size;j++){
                  int random=(int)(Math.random()*51);
                  if(a.[random]==null) //to ensure that only unique nos. are used.
                  {
                  temp.add(values[random]);
                  values[j]=temp.get(j);
                  a.[random]=1;
                  // the above code will only be executed if `a[random]` is null
                  //ensures that this executes only when unique number is generated
              }
              else
              {
                j--; 
              //so that 52 iterations occur successfully. We don't want any iteration to go waste.
              }
           }
          

          我使用了Integer 数组来确保使用唯一的数字。每次生成唯一编号时,我们都会将 1 或其他整数分配给 Integer 数组的特定索引。只有在与生成的整数 random 对应的索引处未设置 a[]'s 值时,才会执行您的依赖代码。

          【讨论】:

          • 你写a.[random]=""的时候到底想表达什么?
          • @AndyTurner 我错过了一个“=”符号。感谢您指出。我将int a[] 更改为Integer a[]
          【解决方案6】:

          您想进行不带替换的随机抽奖,但您已经实现了带替换的随机抽奖...

          将卡片放入大小为 52 的数组中,然后在您的第一次抽签中执行以下操作:

          (int)(Math.random()*51 + 1);
          

          这会给你一个 1-52 之间的随机数,假设你得到 4,然后通过删除第 4 个元素来更新数组,留下一个大小为 51 的数组。然后进行第二次绘制:

          (int)(Math.random()*50 + 1);
          

          等等……

          【讨论】:

            猜你喜欢
            • 2015-01-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-12-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多