我有两个未排序的 32 位无符号整数数组,大小分别为 N1 和 N2。每个数组可能包含重复项。我想将每个值(2^32 个可能的键)映射到大小为(N1 + N2)的字节数组中的一个点,以记录每个键的频率。重复的键值应映射到此数组中的相同位置。此外,每个整数的频率不会超过 100(这就是为什么我选择一个字节数组来记录每个键的频率以节省空间);如果最大可能频率超过此值,我只需将字节数组更改为短裤数组或其他东西。
最后,我需要一个大小为 N1 + N2 的数组——不一定会使用所有条目,因为可能会遇到重复项——每个唯一键值的频率。最坏的情况下,将只使用一个字节条目(例如,两个数组中的所有值都相同)而使 ((N1 + N2) - 1) 个条目未使用。最佳情况下,使用所有字节条目。
据我了解,我需要找到一个最小完美的散列函数来将已知数量的未知键(N1 + N2;所有范围从 0 - 2^32)映射到已知数量的点(N1 + N2)。我能够找到其他一些帖子,但两个答案基本上都说使用 gperf:
第二个(最小完美散列函数)正是我想要做的。
与其期望答案中的源代码(顺便说一句,我正在使用 C),我更愿意解释如何为 N 个桶的任何可能正整数的 N 个创建一个最小完美的散列函数。我可以很容易地使用 4 GB 的直接映射数组来处理具有大量未使用空间的每个可能的整数,但我宁愿尝试减少这种巨大的空间效率低下。我也希望不使用任何外部库,主要用于教育目的,以了解更多关于散列本身的信息。