生成不重复的随机数
Posted
技术标签:
【中文标题】生成不重复的随机数【英文标题】:Generating non-repeating random numbers 【发布时间】:2012-01-23 04:01:37 【问题描述】:我想在 C 中创建一个函数。它将返回一个 N 范围内的随机整数,例如:-
兰德()%N;
但问题是我想跟踪唯一性。我不希望数字重复。但我也可以通过创建一个数组并在其中复制生成的整数来做到这一点。喜欢 :-
array[count] = rand() % N;
并每次检查生成的数字是否已经在其中。 (只需在数组[] 中搜索);这是一种简单但正确的方法。这将需要很多 if's 和 for's;为此工作。
这是我能想到的最好的了。
问题是,我想为这个问题找到最好的/优化的解决方案。最有效的方法是什么?
让我们澄清一些事情:- 我想从一个始终唯一的 NSArray 在 UILabel 中设置一些文本。我的 NSArray 正在从 Plist 获取数据,而我的 Plist 有超过 1000 个条目。如果我想多次这样做会影响性能,所以我想要一些有效的方法来做到这一点。
【问题讨论】:
如果保证没有重复就不再随机了,这不就是逻辑上的吗? “随机”和“唯一”不属于同一个句子。您要解决的具体问题是什么? 可以说我正在尝试用随机数填充一个数组,直到 ceil 为 100,或者 iphone dev 的另一个示例是我在 NSArray 的 1000 个对象的标签中显示随机对象。跨度> @user:你想要做的是有效地shuffle一组数字。这已在各种情况下多次讨论过。 【参考方案1】:听起来你想要的实际上是数字 1..N 的随机排列。因此,用连续整数 1..N 填充一个数组,然后对数组进行洗牌。有well known algorithms for shuffling可以查。
【讨论】:
【参考方案2】:您可以使用超快速高效的bloom filter,而不是数组。如果您要生成大量数字,这将比遍历数组快得多。
【讨论】:
谢谢,是不是我要为iphone设计呢,还是有一个类可以帮我实现,我可以直接用吗? Apple 没有提供这样的结构。尽管您可以在某个地方使用可能的库。我自己从来没有用过,所以不能提供更多建议。【参考方案3】:使用某种哈希表来存储已经生成的数字并快速检查该数字是否已经看到。我不完全知道您要做什么,但是由于您需要唯一的 rand,我想您正在尝试置换一个有限集,如果是这种情况,请查看一些 Shuffling Algorithms。
【讨论】:
【参考方案4】:四个选项,在内存和时间上都是O(1):
-
只需增加一个全局计数器。由于您需要唯一性,因此无论如何您都无法生成随机数。
从一个足够大的集合中生成一个数字,该数字极不可能重复。 64 位足以满足应用内唯一性; 128 位足以实现全局唯一性。这就是UUIDs 的工作方式。
如果选项 1 对您来说不够“随机”,请使用所述全局(32 位)计数器的 CRC-32 哈希。 N 位整数与其 CRC-N 之间存在 1 对 1 映射(双射),因此仍然可以保证唯一性。
使用Linear Feedback Shift Register 生成数字。这些是 N 位计数器,以看似“随机”(尽管显然是确定性的)模式计数。出于您的目的,这基本上是选项 3 的一个稍快的版本。
【讨论】:
【参考方案5】:所描述的算法非常糟糕,因为它在新数组中搜索每个新条目。这意味着随着数组的增长,它必须搜索越来越多的数据,更糟糕的是,随着剩余项目数量的减少,它最终会循环更多。
例如,如果您有一个从 1…10 的列表,当您填写了 8 个项目时,只剩下两个项目(比如 7 和 9),现在,每次生成一个随机数时,它都会生成80% 的时间是非唯一数字,并且必须扫描至少六个条目才能检测到重复项。
在某些库中可能有一些更好的方法,但比问题中更好的方法是创建一个(链接的)项目列表,随机选择一个,删除它,并将其添加到新列表中。这样,每次您随机选择一个时,都可以保证它是唯一的,因为使用过的不再在池中。
【讨论】:
以上是关于生成不重复的随机数的主要内容,如果未能解决你的问题,请参考以下文章