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

时间:2011-12-08 12:55:24

标签: c++ c algorithm

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

首先想到的是使用二叉树创建并在树中找到重复项(如果有的话)。   但这可能不是很有效。

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

有没有更好的方法呢?

6 个答案:

答案 0 :(得分:2)

生成N个连续字符串,然后执行random shuffle以随机顺序将它们拉出。如果它们需要在不同的生成器中是唯一的,请将唯一的生成器ID混合到字符串中。

答案 1 :(得分:1)

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

至于你的问题,它取决于许多限制:字符串是短还是长?他们必须有意义吗?等等......我头脑中的两个解决方案:

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

2简单地生成随机字符串并将它们放入可搜索的结构(HashMap)中,这样如果生成的字符串已经有重复,您可以非常快速地找到(O(1)-O(log n)),在这种情况下它被丢弃了。

答案 2 :(得分:0)

树可能不是最有效的,特别是对于插入 - 因为它必须不断地重新平衡自己(有点“昂贵”的操作)。

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

  

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

答案 5 :(得分:0)

二叉树在这里可能比平常更好 - 不需要重新平衡,因为你的字符串是随机的,并且随机数据表明二进制树是最好的。但是,它仍然是O(log(n))用于查找和添加。

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

布隆过滤器提供了一种有效的概率集合成员测试,其内存要求低至集合中保存的每个元素一位。基本上,布隆过滤器可以100%确定地说一个成员不属于一个集合,但是一个成员在一个集合中具有高但不是100%的确定性。在你的情况下,抛出一两个额外的候选人应该不会受到伤害,所以概率性质不应该有点伤害。

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

有一段时间,我在这里列出了treaps,但这很愚蠢 - 他们再次在O(log(n))中做了很多操作,并且只有在你的数据不是真正随机的情况下才会相关。

如果由于某种原因你不需要保存你的字符串(听起来你可能没有),传统的哈希表是一个很好的方法。他们想知道你的最终数据集有多大(为了避免缓慢的哈希表调整大小),但它们也是插入和查找的恒定时间。

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