0

给定一个由 6 个唯一字符串组成的数组(我事先不知道并且总是以随机顺序给出)我如何映射这些字符串以便可以为每个字符串分配一个 1-6(或 0-5)的数字. 并在下一个脚本运行时分配相同的编号?

我还应该补充一点,并不是所有的字符串都会在每个脚本运行时传递

例如

// Script Run 1: 
string1 => 2
string2 => 6
string3 => 5
string6 => 1


// Script Run 2: 
string3 => 5
string4 => 4
string2 => 6
string5 => 3

// Note how strings 2 and 3 have the same mapping

我假设一些类似于散列和 mod(6) 的东西,但不确定如何实现。有什么建议么?

注意:这是在脚本中,会话不可用

提前致谢

4

1 回答 1

1

分配数字的模数用法示例

由于要求每个字符串限制在 0 到 5 或 1 到 6 之间的数字,并且数据集不断变化/不完整,因此不可能达到预期的最终结果。假设我们取 6 个字符串,我们将对它们进行 crc,然后进行模数 6 并显示结果。输入:

Array
(
    [0] => string1
    [1] => string2
    [2] => string3
    [3] => string4
    [4] => string5
    [5] => string6
)

crc32使用sprintf('%u', crc32('string'))

Array
(
    [0] => 742935113
    [1] => 3040943091
    [2] => 3259378533
    [3] => 1545780934
    [4] => 723881552
    [5] => 2989285354
)

结果crc32 % 6

Array
(
    [0] => 5
    [1] => 1
    [2] => 1
    [3] => 4
    [4] => 2
    [5] => 1
)

如您所见,“string2”、“string3”和“string6”都与发生冲突,导致它们被分配一个“1”,通过碰撞检测,一个简单的+1直到找到一个空桶将用于这个例子。所以我们最终得到了我们的bucket数组:

Array
(
    [0] => string6
    [1] => string2
    [2] => string3
    [3] => string5
    [4] => string4
    [5] => string1
)

下一次,假设我们摆脱[1] => string2了原始输入,那么我们的 6 个结果数组将如下所示:

Array
(
    [0] => 
    [1] => string3
    [2] => string5
    [3] => string6
    [4] => string4
    [5] => string1
)

这显示了当数据集不完整且包含少量键时会发生什么,分配的数字对于某些人来说是截然不同的。

问题是load. 这个负载是 100%,因为有 6 个可能的文本,并且只有 6 个buckets。创建哈希表时,您希望负载接近 0,对于 6 个条目的 50% 负载,您需要 12 个可用存储桶。

记住

在 PHP 中使用 amodulus时,您还必须记住最大整数大小,因为用于模运算的任何值都将转换为整数

模数的操作数在处理之前被转换为整数(通过去除小数部分)。

根据您的系统,这将是 32 位或 64 位。一个无符号的 crc32 将超过 32 位系统上的最大上限并返回 int 上限,这意味着一半的数字将在同一个桶中结束(统计上),这正是我们之前一半的值在桶 '1 中结束时发生的情况'。

我们能做些什么?

好吧,问题是我们可以选择的数字范围。根据分配不同字符串数字的所需应用程序,我们可以使用实crc32数,因为对于小数据集,结果中的冲突数量将是最小的 - 但是,如果我们需要输入文本的连续数字集(或在如所描述的一个小范围),没有解决方案可以允许部分数据集,同时在每次运行中保持分配的数字不变。由于每次运行脚本时输入字符串的顺序都是随机的,因此绝对没有办法每次都保持结果整数相同,因为如果在每次运行之间的不同时间处理冲突,它们的顺序可能会颠倒。

如果目的是标记文件或访问某些内容的方式,请使用更大的散列,不要mod让它适合它的大小。

于 2013-02-13T04:05:12.463 回答