生成没有重复项的随机字符串的正确方法是什么

What's the correct way to generate random strings without duplicates

本文关键字:字符串 随机 是什么 方法      更新时间:2023-10-16

我正在考虑生成随机字符串,而不进行任何复制。

第一个想法是使用二叉树来创建和定位树中的重复项(如果有的话(。但这可能不是很有效。

第二个想法是使用类似MD5的哈希方法,该方法只基于时间创建消息,但这可能会引入另一个问题,不同的机器具有不同的时间准确性。在现代处理器中,在一个时间戳中可以创建多个字符串。

有更好的方法吗?

生成N个连续字符串,然后进行随机洗牌,以随机顺序将它们拉出。如果它们需要在单独的生成器之间是唯一的,请将唯一的生成器ID混合到字符串中。

注意MD5,不能保证两个不同的字符串不会生成相同的哈希。

至于你的问题,它取决于许多约束:字符串是短的还是长的?它们一定要有意义吗?等等…我脑海中浮现的两个解决方案:

1生成UUID,然后使用二进制表示或base64算法将它们转换为String。

2只需生成随机字符串,并将其放入可搜索的结构(HashMap(中,这样您就可以非常快速地找到(O(1(-O(logn((生成的字符串是否已经有重复,在这种情况下,它将被丢弃。

树可能不是最高效的,尤其是对于插入,因为它必须不断地重新平衡自己(有点"昂贵"的操作(。

我建议使用HashSet类型的数据结构。哈希算法应该已经非常高效了(比MD5之类的算法更高效(,并且所有操作都是恒定时间的。将所有字符串插入集合。如果您创建了一个新的String,请检查它是否已经存在于Set中。

听起来你想生成一个uuid?看见http://docs.python.org/library/uuid.html

>>> import uuid
>>> uuid.uuid4()
UUID('dafd3cb8-3163-4734-906b-a33671ce52fe')

您应该指定要用什么编程语言进行编码。例如,在Java中,这将很好地工作:UUID.randomUUID().toString()。UUID标识符在实践中是唯一的,正如wikipedia:中所述

UUID的目的是使分布式系统能够在没有重要的中央协调的情况下唯一地识别信息。在这种情况下,"唯一"一词应被视为"实际唯一",而不是"保证唯一"。由于标识符具有有限的大小,因此两个不同的项目可以共享相同的标识符。需要选择标识符的大小和生成过程,以便在实践中充分避免这种情况。

这里的二进制树可能比平时更好-不需要重新平衡,因为字符串是随机的,二进制树在随机数据上工作得最好。然而,对于查找和添加,它仍然是O(log(n((。

但是,如果你事先知道你需要多少随机字符串,并且不介意混合中的一点概率,也许更有效的方法是使用bloom过滤器。

Bloom过滤器提供了一种高效的、概率性的集合成员身份测试,其中存储在集合中的每个元素的内存需求低至一位。基本上,bloom过滤器可以100%确定地说成员不属于集合,但可以很高但不完全100%确定地表示成员在集合中。在你的情况下,抛出一两个额外的候选人应该一点都不疼,所以概率性的本质应该一点也不疼。

Bloom过滤器也相对独特,因为它们可以在恒定时间内测试集合成员身份。

有一段时间,我在这里列出了treap,但这很愚蠢——它们在O(log(n((中又做了很多运算,只有当你的数据不是真正随机的时,它们才是相关的。

如果出于某种原因不需要按顺序保存字符串(听起来可能不需要(,那么使用传统的哈希表是一个不错的方法。他们喜欢提前知道您的最终数据集有多大(以避免哈希表调整大小缓慢(,但它们也是插入和查找的恒定时间。

http://stromberg.dnsalias.org/svn/bloom-filter/trunk/