【问题标题】:Non-repeating random numbers inside array JAVA数组JAVA中的非重复随机数
【发布时间】:2014-02-12 12:38:38
【问题描述】:

我想在一个数组中生成 6 个数字,同时进行比较,这样它就不会是相同的数字或没有重复的数字。例如,我想以任意顺序生成 1-2-3-4-5-6,最重要的是不重复。所以我的想法是在生成的数组中一一比较当前数组,如果数字重复,它将重新运行该方法并再次随机化一个数字,以避免数字重复。

这是我的代码:

import javax.swing.*;
public class NonRepeat
{
    public static void main(String args[])
    {
        int Array[] = new int [6];
        int login = Integer.parseInt(JOptionPane.showInputDialog("ASD"));
        while(login != 0)
        {
            String output="";

            for(int index = 0; index<6; index++)
            {
                Array[index] = numGen();

                for(int loop = 0; loop <6 ; loop++)
                {
                    if(Array[index] == Array[loop])
                    {
                        Array[index] = numGen();
                    }
                }


            }

            for(int index = 0; index<6; index++)
            {
                output += Array[index] + " ";
            }


            JOptionPane.showMessageDialog(null, output);

        }



    }

    public static int numGen()
    {
        int random = (int)(1+Math.random()*6);
        return random;
    }
}

我已经考虑了 2 个小时,但仍然无法生成 6 个数字而不重复。 希望我的问题能得到解答。

顺便说一句,我是新代码,所以我只想使用for 循环或while 循环和if else 比较它。

【问题讨论】:

  • 我的第一个想法是,如果你想要真正的随机数,你应该允许重复。如果您生成一个随机数,然后检查子句,将其丢弃,然后生成另一个随机数,则生成的数组将不包含完全随机数。
  • 您可以将生成的数字添加到Set 中(它会自动删除重复项),直到Setsize()6,然后将Set 转换为数组使用toArray()
  • @EricTobias 检查条款是什么意思?
  • @sp00m 我不知道 Set 是什么东西。对不起。
  • 子句是一个逻辑语句。因此,检查您的数据结构是否已经包含相同的随机数将是一个子句。

标签: java arrays random


【解决方案1】:

您可以从 1 到 6 生成数字(另一种解决方案请参见下文),然后执行 Collections.shuffle 来打乱您的数字。

    final List<Integer> l = new ArrayList<Integer>();
    for (int j = 1; j < 7; j++ ) {
        l.add( j );
    }
    Collections.shuffle( l );

通过这样做,您最终会得到一个从 1 到 6 的随机数字列表,而不会有两倍的相同数字。

如果我们分解解决方案,首先你有这个,它实际上只是创建了一个包含六个数字的列表:

    final List<Integer> l = new ArrayList<Integer>();
    for (int j = 1; j < 7; j++ ) {
        l.add( j );
    }

因此,此时您拥有您在问题中提到的列表 1-2-3-4-5-6。保证这些数字不会重复。

然后,您只需通过将每个元素与另一个元素交换至少一次来随机化该列表。这就是Collections.shuffle 方法的作用。

您建议的解决方案不会非常有效:根据您的数字列表的大小和范围,您可能有很高的概率出现重复数字。在这种情况下,不断地重新尝试生成新列表会很慢。此外,如果您有很长的连续数字列表(例如从 1 到 100 000 的 100 000 个数字的列表),则任何其他建议检查列表是否已包含数字以防止重复或使用集合的解决方案都会很慢:您会不断尝试随机生成尚未生成的数字,并且随着数字列表的增长,您会遇到越来越多的冲突。

如果您不想使用Collections.shuffle(例如出于学习目的),您可能仍想使用相同的想法:首先通过确保没有任何重复来创建您的数字列表,然后执行for 循环随机交换列表的两个元素。您可能想查看Collections.shuffle 方法的源代码,该方法以正确的方式进行随机播放。

编辑您的“随机数”的属性必须是什么还不是很清楚。如果您不希望它们从 1 递增到 6,则可以执行以下操作:

final Random r = new Random();
final List<Integer> l = new ArrayList<Integer>();
for (int j = 0; j < 6; j++ ) {
    final int prev = j == 0 ? 0 : l.get(l.size() - 1);
    l.add( prev + 1 + r.nextInt(42) );
}
Collections.shuffle( l );

请注意,通过将 r.nextInt(42) 更改为 r.nextInt(1),您将有效地获得从 1 到 6 的非重复数字。

【讨论】:

  • 我认为他在你的情况下要求唯一的随机数你没有给他从 1 到 7
  • @IndraYadav:他清楚地举了一个数字从 1 到 6 的例子,但我会编辑我的答案以反映这两种情况。
  • @IndraYadav:已编辑以允许按顺序或不按顺序生成数字,使用相同的“一个 for 循环,一个 shuffle”解决方案。
  • @TacticalCoder 我不知道这段代码是如何工作的,但我正在尝试。对不起。但是如果会慢的话,我把1-6改成1-42怎么办?
  • @lazygeniusLANZ:生成 42 个数字的列表?它会非常快。使用第二种解决方案生成 100 000 个数字的列表在我的系统上需要 25 毫秒......我建议的解决方案在复杂性上是 O(n) 并且在现代 CPU 上每秒执行数十亿次操作真的很快。希望对您有所帮助。
【解决方案2】:

您必须检查号码是否已经存在,您可以通过将号码放入List 轻松做到这一点,因此您可以访问方法contains。如果您坚持使用数组,那么您可以创建一个循环来检查该数字是否已经在数组中。

使用ArrayList

ArrayList numbers = new ArrayList();

while(numbers.size() < 6) {
    int random = numGen(); //this is your method to return a random int

    if(!numbers.contains(random))
        numbers.add(random);
}

使用数组:

    int[] numbers = new int[6];

    for (int i = 0; i < numbers.length; i++) {
        int random = 0;

        /*
         * This line executes an empty while until numGen returns a number
         * that is not in the array numbers yet, and assigns it to random
         */
        while (contains(numbers, random = numGen()))
            ;


        numbers[i] = random;
    }

并将此方法添加到上面的 sn-p 中使用的某处

private static boolean contains(int[] numbers, int num) {
    for (int i = 0; i < numbers.length; i++) {
        if (numbers[i] == num) {
            return true;
        }
    }
    return false;
}

【讨论】:

  • 我想使用数组,因为它现在是我们的主要课程。我在第一个 for 循环中做了一个循环,但它不起作用。
  • @lazygeniusLANZ 我也用数组的例子更新了帖子。希望现在有用
【解决方案3】:

这是根据您的代码的解决方案-

你只需要改变 numGen 方法 -

public static int numGen(int Array[])
{

    int random = (int)(1+Math.random()*6);

    for(int loop = 0; loop <Array.length ; loop++)
    {
        if(Array[loop] == random)
        {
            return numGen(Array);
        } 
    }


    return random;
}

完整的代码是 -

import javax.swing.*;
public class NonRepeat
{
    public static void main(String args[])
    {

        int login = Integer.parseInt(JOptionPane.showInputDialog("ASD"));
        while(login != 0)
        {
            int Array[] = new int [6];
            String output="";

            for(int index = 0; index<6; index++)
            {
                Array[index] = numGen(Array);


            }

            for(int index = 0; index<6; index++)
            {
                output += Array[index] + " ";
            }


            JOptionPane.showMessageDialog(null, output);

        }



    }

    public static int numGen(int Array[])
    {

        int random = (int)(1+Math.random()*6);

        for(int loop = 0; loop <Array.length ; loop++)
        {
            if(Array[loop] == random)
            {
                return numGen(Array);
            } 
        }


        return random;
    }
}

【讨论】:

  • 我什至不知道为什么这被否决了,但这确实解决了我的问题,并用我理解的最简单的代码回答了我的问题。
  • 递归?严重地?为什么?不需要递归。解决这个问题所需要做的就是用数字初始化一个数组并随机交换元素 N 次。
【解决方案4】:

使用List 代替数组和List#contains 来检查数字是否重复。

【讨论】:

    【解决方案5】:

    您可以在 while 循环中使用布尔值来识别重复项并重新生成

    int[] array = new int[10]; // array of length 10
    
    Random rand = new Random(); 
    
        for (int i = 0 ; i < array.length ; i ++ ) {
    
            array[i] = rand.nextInt(20)+1;  // random 1-20
    
            boolean found = true;
    
            while (found) { 
    
            found = false; 
      // if we do not find true throughout the loop it will break (no duplicates)
    
             int check = array[i]; // check for duplicate 
    
                 for (int j = 0 ; j < i ; j ++) {
    
                     if ( array[j] == check ) {
    
                     found = true; // found duplicate                   
                     }
                 }          
    
                  if (found) {  
                        array[i] = rand.nextInt(20)+1 ;   // replace    
                  }
            }
        }
    
    System.out.println(Arrays.toString(array));
    

    【讨论】:

      【解决方案6】:

      您可以使用java.util.Random。如果您想要任何随机数或只是数字 1、2、3、4、5、6,请指定。如果你想要随机数,那么这是一个基本代码:

      import java.util.*;
      public class randomnumber
      {
          public static void main(String[] args)
          {
              Random abc = new Random();
              int[] a = new int[6];
              int limit = 100,c=0;
              int chk = 0;
              boolean y = true;
              for(;c < 6;)
              {
                  int x = abc.nextInt(limit+1);
                  for(int i = 0;i<a.length;i++)
                  {
                      if(x==a[i])
                      {
                          y=false;
                          break;
                      }
                  }
                  if(y)
                  {
                      if(c!=0)if(x == (a[c-1]+1))continue;
                      a[c]=x;
                      c++;
                  }
              }
      
              for (Integer number : a) 
              {
                  System.out.println(number);
              }
          }
      }
      

      如果你不明白最后一个for循环,请告诉我,我会更新它。

      【讨论】:

      • 最初我想从 1-42 生成数字,但我们的教授通过使用 1-6 为他检查它以确保没有任何重复。老实说,我不理解你的大部分代码。我只知道基础。 :(
      【解决方案7】:

      使用 List 和 .contains(Object obj) 方法。 所以你可以验证list之前是否添加了随机数。

      更新 - 根据时间你可能会迷失在随机循环中。

          List<Integer> list = new ArrayList<Integer>();
          int x = 1;
          while(x < 7){
      
                      list.add(x);
                      x++;
          }
          Collections.shuffle(list);
      
          for (Integer number : list) {
              System.out.println(number);
          }
      

      http://docs.oracle.com/javase/7/docs/api/java/util/List.html#contains(java.lang.Object)

      【讨论】:

      • 随机性是随机的!你的 while 可能不会在你的一生中终止。虽然不可能,但有可能。我会避免这种做法,并建议编写可以确定计算时间复杂度的代码。
      • 你是对的,这就是为什么洗牌是一件很酷的事情。如果您认为在一个大场景中,这很糟糕。我刚刚为我们的伙伴发布了一个不同的示例;)
      猜你喜欢
      • 1970-01-01
      • 2013-04-06
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      相关资源
      最近更新 更多