【问题标题】:Algorithm for finding random and unique number in a range [duplicate]在范围内查找随机和唯一数字的算法[重复]
【发布时间】:2014-05-21 07:12:13
【问题描述】:

我想知道一种算法来找到不可重复的唯一随机数。每次我在程序中调用它时,都应该给出一个唯一的随机数,这是该算法以前没有给出的。我想知道,因为在游戏或应用程序中的某些时候出现了这种要求。

例如。在游戏中,我创建了一些对象并将它们全部保存在一个数组中,并希望通过随机且唯一的方式检索它们,并且不想从数组中删除。这只是一个场景。

我尝试了一些替代方案,但它们的性能并不好,从未得到这个问题的答案。

如何以编程方式实现?

提前致谢。

【问题讨论】:

标签: algorithm random unique


【解决方案1】:

以下代码生成 1-15 的唯一随机数。根据您的要求修改:-

public class Main
{
     int i[]= new int[15];
        int x=0;
        int counter;

     public int getNumber()
     {
          return (int)((Math.random()*15)+1);
     }
     public int getU()
     {
            x = getNumber();
            while(check(x))
            {
                x = getNumber();
            }
            i[counter]=x;
            counter++;
            return x;
     }
        public boolean check(int x)
        {
            boolean temp = false;
            for(int n=0;n<=counter;n++)
            {
                if(i[n]==x)
                {
                    temp = true;
                    break;
                }
                else
                {
                    temp = false;
                }
            }
            return temp;
        }
     public static void main(String args[])
     {
          Main obj = new Main();

          for(int i=0;i!=15;i++)
          {
               System.out.println(obj.getU());
          }
     }
}

有关更多信息,请参阅以下链接:-

https://community.oracle.com/message/4860317

Expand a random range from 1–5 to 1–7

【讨论】:

  • 有这么多链接,这是最好的方法吗?
  • @user2864740 你认为这不是一个很好的帮助方法吗?因为如果你认为那么以后记得
  • 在至少 2 个 [相关] 链接中有更好的解决方案 - 阅读它们并将知识整合到解决方案中可能是值得的,而不是仅仅抓取(和复制)第一个结果.
  • @user2864740 感谢您的建议,以后也要记住这个答案!!!
  • @Golu 谢谢,这种方法好吗,如果我们想要大量的值,考虑到性能,因为你使用一些循环和数组来保存这些值。
【解决方案2】:

在我看来,最好的选择是从输入列表中删除返回的数字。
让我解释一下:

从整个范围开始,例如:range = [0, 1, 2, 3, 4]
折腾一个随机索引,比如说 3。
现在从 range 中删除 range[3],你得到 range = [0, 1, 3, 4]

等等。
这是python中的示例代码:

import random
rangeStart = 0
rangeEnd = 10
rangeForExample = range(rangeStart, rangeEnd)
randomIndex = random.randrange(rangeStart, rangeEnd)
randomResult = rangeForExample[randomIndex]
rangeForExample.remove(randomResult)

【讨论】:

    【解决方案3】:

    这可以通过多种方式实现。这是其中两个(目前在我的头上):

    1. 保留先前生成的值。(用于基于范围的随机编号生成) 在这种方法中,您生成一个随机数并将其存储(在文件或数据库中),以便在您生成下一个编号时。您可以将其与之前的数字匹配,如果已经生成,则将其丢弃。

    2. 每次都生成一个唯一编号。 (用于基于非范围的随机编号生成) 在这种方法中,您使用一个序列或类似的东西,它可以为您提供唯一的数字,例如当前时间毫秒。

    【讨论】:

      【解决方案4】:
      1. 获取阵列的count
      2. 在 (0, count) 之间随机分配一个 index
      3. 在数组中检索index 的项。
      4. index 删除该项目。

      我看到你在做 iOS,我会举一个 Objective-C 的例子。

      NSMutableArray *array = <creation of your array>;
      
      int count = array.count;
      
      while (1) {
      
          int randomIndex =  arc4random() % count;
      
          id object = [array objectAtIndex:randomIndex];
      
          NSLog(@"Random object: %@", object);
      
          [array removeObject:object];
          count--; // This is important
      
          if(array.count == 0)
          {
              return;
          }
      }
      

      【讨论】:

      • 谢谢,但是在这种方法中,您的对象将从数组中删除,我也想在以后使用这个数组。
      • @Neeraj 如果您以后想重用您的对象,那么unique 的意义何在?如果是这种情况,您可以通过我的方法将您的array 复制到一个临时的。
      【解决方案5】:

      这是我能想到的两个选项..

      使用历史列表

      1. Keep past picked random numbers in a list
      
      2. Find a new random number
      
      3. If the number exist in history list, go to 2
      
      4. [optional] If the number lower history list randomness, go to 2
      
      5. add the number to the history list
      

      使用跳跃

      At Time 0: i=0; seed(Time); R0 = random() % jump_limit
      
      1. i++
      
      2. Ji = random() % jump_limit
      
      3. Ri = Ri-1 + Ji
      

      【讨论】:

        猜你喜欢
        • 2014-05-15
        • 2011-10-30
        • 2011-08-02
        • 2018-04-22
        • 2014-07-09
        • 1970-01-01
        • 1970-01-01
        • 2011-05-16
        • 1970-01-01
        相关资源
        最近更新 更多