生成非重复随机数

时间:2011-12-18 19:44:23

标签: objective-c c logic

我想在C中创建一个函数。它将返回一个N范围内的随机整数,如: - rand()%N; 但事情是我想跟踪独特性。我不想重复这些数字。但我也可以通过制作一个数组并复制生成的整数来做到这一点。喜欢 :- array[count] = rand() % N;并且每次检查生成的数字是否已经在其中。 (只需在数组[]中搜索;这是一个简单的方法,但是正确的方法。这需要很多,如果有的话;为此工作。 这是我能想到的最好的。


问题是,我想为此问题获得最佳/优化的解决方案。最有效的方法是什么?

让我们清楚一些事情: - 我想在NSArray的UILabel中设置一些永远是唯一的文本。我的NSArray从Plist获取数据,我的Plist有超过1000个条目。如果我想多次这样做会影响性能,所以我想要一些有效的方法来做到这一点。

5 个答案:

答案 0 :(得分:6)

听起来你想要的实际上是数字1..N的随机排列。因此,用连续的整数1..N填充数组,然后将数组洗牌。您可以查看well known algorithms for shuffling

答案 1 :(得分:1)

使用某种哈希表来存储已生成的数字并快速检查已经看到的数字。我不知道你想要做什么,但是因为你需要独特的兰特,我猜你试图置换一个有限的集合,如果是这样的话,看一下Shuffling Algorithms。< / p>

答案 2 :(得分:1)

您可以使用超快速高效bloom filter而不是数组。如果你生成任何大量的数字,这将比循环数组更快。

答案 3 :(得分:1)

四个选项,所有这些选项在内存和时间都是 O (1):

  1. 只需增加一个全局计数器。由于您需要唯一性,因此无论如何都无法生成随机数。
  2. 从一个足够大的集合中生成一个数字,以至于数字重复的可能性很小。 64位足以满足应用内的独特性; 128位足以实现全局唯一性。这就是UUID的工作方式。
  3. 如果选项1对您来说不够“随机”,请使用所述全局(32位)计数器的CRC-32哈希值。 N位整数与它们的CRC-N之间存在一对一的映射(双射),因此仍然可以保证唯一性。
  4. 使用Linear Feedback Shift Register生成数字。这些是N位计数器,它们以一种看似“随机”(虽然明显是确定性的)模式计数。为了您的目的,这实际上是选项3的适度更快的版本。

答案 4 :(得分:0)

所描述的算法非常糟糕,因为它为每个新条目搜索新数组。这意味着随着阵列的增长,它必须搜索越来越多的数据,更糟糕的是,随着剩余项目数量的减少,它将最终循环更多。

例如,如果您有1 ... 10的列表,当您填写了8个项目时,只剩下两个项目(比如7和9),现在,每次生成一个随机数时,它都会生成80%的时间是非唯一数字,在检测到重复之前必须扫描至少六个条目。

在某些库中可能有一些更好的方法,但是比问题更好的方法是创建(链接)项目列表,随机选择一个,删除它,并将其添加到新列表中。这样,每次你选择一个随机的,它保证是唯一的,因为使用过的那些不再在池中。