假设我有一个唯一数字列表(例如105,342,432,34等),我想将它们映射到索引(0,1,2,3等)。有没有一般的方法来做到这一点?如果没有,假设您事先知道列表中的所有数字,并且您可以对其值进行硬编码。如果这没有帮助,另一个限制因素可能是数字“几乎是连续的”。这意味着它们在大多数情况下是连续的,但可能存在间隙(您提前知道)。
答案 0 :(得分:1)
您要做的主要是实现哈希映射(或字典)。许多语言有许多库可以实现这种结构
以简单的方式在幕后发生的事情是,例如,一个数组和散列函数,它将您的数字映射到数组的一个索引,以实现对基于元素的O(1)摊销访问在他们的钥匙上
第二个重要方面是如何处理碰撞。例如,您的数字的哈希函数为f(x) = x mod 10
。 13 和 33 都将被散列为 3 。这是一次碰撞,必须加以处理。例如,您可以创建有序的元素列表并将它们分配给阵列的插槽。搜索元素时,您将对其键进行散列并在指定数组的位置搜索列表以进行精确的键匹配
这只是一切的开始,你可能会发现有关这一切的更多信息
维基百科上的Hash function和Hash map
值得一提的是,在您的情况下,您只想自己存储密钥。通常我们需要存储更复杂的对象并通过其键来搜索它们,这些键通常是数字或字符串,但也可以是任何类型的更复杂的对象。
修改强>
我刚刚意识到,您的问题更多的是为您的特定场景找到最佳哈希函数,而不是更类似于您的问题的更一般解决方案。
如果我理解正确,你是说你事先知道这些数字?如果确实如此,你可以 if if 将数字中的每一个分配给数组中的一个索引,以一种非常硬编码的形式(如你自己建议的那样),例如:
if (num == 105)
idx = 0;
else if (num == 342)
idx = 1;
...
如果你不知道你的数字,但是你知道,比如最小和最大的数字,你可以将它们哈希到索引:
f(x) = (x - smallest_num) mod (greatest_num - smallest_num + 1)
在这种情况下,f(x)
是一个完美的散列函数,这意味着不会有任何碰撞。鉴于您的数字并不总是连续的,您的阵列仍会将其部分插槽清空。
注意:我仍然不确定你打算怎么做,因此我不确定我是否正确回答了你的问题。特别是事先你可能知道你的数字,或者你可能对它们了解很多,这让我很困惑。也许如果您的目的得到澄清,我们可以为您提供不同方式实现目标的方法。