用于将字符串范围均匀分布到存储桶中的Java算法

时间:2013-09-15 17:20:39

标签: java string algorithm

简短版本 - 我正在寻找一种Java算法,该算法给出一个String和一个表示多个桶的整数,返回将String放入哪个桶。

长版 - 我需要将大量对象均匀地(或大致均匀地)分配到容器中。箱柜/桶的数量会有所不同,因此算法不能假设特定数量的箱柜。它可能是1,30或200.这些对象的键是String。

String具有一些重要的可预测品质。字符串的前2个字符实际上看起来是一个字节的十六进制表示。即00-ff,并且字符串本身在该范围内非常均匀地分布。虽然有几个异常值开始不同,所以这不能依赖于100%(尽管很容易99.999%)。这只是意味着需要处理边缘情况。

至关重要的是,一旦分配了所有字符串,在任何2个区间中出现的值之间的范围内没有重叠。所以,如果我知道bin中出现的值范围,我不必查看任何其他bin来查找对象。因此,例如,如果我有2个bin,则可能是bin 0的字符串以字母a-m开头,bin 1以n-z开头。但是,考虑到我们对字符串的了解,这并不能满足均匀分布的需要。

最后,实现可能不知道箱的当前状态。方法签名应该是:

public int determineBucketIndex(String key,int numBuckets);

我认为关于字符串分布的预知应该足够了。

编辑:澄清一些问题 桶的数量可以超过256.字符串在前2个后面包含其他字符,因此可以利用它。

存储桶应该包含一系列字符串,以便以后快速查找。事实上,这就是为什么他们开始被分类的原因。只有范围的知识,我应该能够正好查看1桶,看看价值是否存在。我不应该去看别人。

哈希德克斯不会工作。我需要桶只包含String值的某个范围内的String(而不是散列)。哈希会失去这一点。

编辑2:显然没有很好地沟通。 选择垃圾箱后,这些值将写入文件。每箱1个文件。分箱后使用这些文件的系统不是Java。它已经实现了,它需要适合一个范围的容器中的值。我再说一遍,hashcode不起作用。我明确表示字符串的范围不能在两个bin之间重叠,使用hashcode不起作用。

3 个答案:

答案 0 :(得分:1)

我已经阅读了两次你的问题,但我仍然不明白这些限制。因此,我在这里提出建议,你可以提供反馈。如果这不起作用,请解释原因。

首先,对箱数进行一些计算,以确定唯一箱号所需的位数。以对数为基数2的二进制数,然后取位数的上限除以8.这是您需要的数据字节数numBytes

取前两个字母并将它们转换为一个字节。然后抓取numBytes - 1个字符并将它们转换为字节。取字符的序数值('A'变为65,依此类推)。如果下一个字符可能是Unicode,请选择一些规则将它们转换为字节...可能会获取最低有效字节(模数为256)。总计numBytes个字节,包括前两个字母的字节,并转换为整数。使前两个字母的字节为整数的最低有效8位,下一个字节为后8个有效位,依此类推。现在简单地将该值的模数乘以箱的数量,并且您有一个整数箱号。

如果字符串太短并且没有其他字符可以转换为字节值,请对每个缺少的字符使用0

如果有任何可预测的字符(例如,第三个字符始终是空格),则不要使用这些字符;跳过它们。

现在,如果这对您不起作用,请解释原因,然后我们也可以很好地理解这个问题。

答案 1 :(得分:0)

在原始帖子的2次更新后编辑回复

从一开始就在您的问题中包含所有信息是一个绝好的主意 - 通过新的编辑,您的描述已经为您提供了答案:将您的对象粘贴到平衡树中(为您提供均匀的分布)你需要)基于你的字符串substring(0,2)的hashCode或类似的基于头部的东西。然后将BTree中的每个叶子(作为一组字符串)写入文件。

答案 2 :(得分:0)

我严重怀疑所描述的问题可以完美地完成。怎么样:

  1. 创建257个垃圾箱。
  2. 将所有正常的字符串放入0-255个字符串。
  3. 将所有异常值放入bin 256。
  4. 除了"均匀分发",这不符合您的所有要求吗?

    此时,如果您真的想要更均匀的分布,您可以将分箱0-255重组为更少数量的均匀分布的分档。但我认为你可能只需要在那里提出要求。