【发布时间】:2021-01-26 04:07:15
【问题描述】:
我正在尝试编写一个函数,它接受一个整数数组,并输出一个哈希值来表示它们的排列顺序。哈希键应该尽可能小(我们正在处理嵌入式和空间/执行优化是至关重要的)
template<size_t N>
int CalculateHashOfSortOrder(int* itemsBegin)
{
// return ???
}
换句话说,数组[ 4, 2, 1, 3 ] 应该产生一个反映它们的顺序的ID,并匹配以下任何数组:
[ 4, 2, 1, 3 ]
[ 4, 2, 0, 3 ]
[ 400, 200, 100, 300]
et al
我不知道如何以最有效的方式做到这一点。解决这个问题的算法是什么?我想出的方法似乎非常缓慢。
例如,给定上面的例子,有 24 种可能的排列 (4 * 3 * 2 * 1),它们适合 5 位。这些位可以这样计算:
- 第一个值 (1)。可能有 4 个位置,因此需要 2 位来描述其位置。该值位于位置 2(从 0 开始)。所以推送二进制
10。 - 第二个值 (2)。可能有 3 个位置,因此需要 2 个位。它在位置 1,所以推送二进制
01。哈希键现在是1001b。 - 第三个值 (3)。可能有 2 个位置,因此需要 1 个位。它位于剩余值的第 1 位,因此请推送
1。
生成的密钥是10011b,但我看不出有什么明确的方法可以做到这一点,但效率极低。我认为还有另一种方法可以解决我从未想过的问题。
编辑:我想到了几个想法:
- 计算数组中每一项的排名,并对排名数组进行哈希处理。那么通过什么方法可以将该排名数组打包成理论上最小的 ID?这似乎是我的问题中最令人头疼的部分。
- 找到一种在插入项目时保存项目排名的方法,优化 #1
- 对于足够少的 # 项 (if() 语句树。需要查看 exe 大小是否有问题。
【问题讨论】:
-
“令人讨厌的低效”——在太空中?还是计算的笨拙? 5 位 几乎 是理论上的最小值。对于 4 个项目,它是最小值(5 位);对于 5 个项目,你会得到 8 位,但理论上的最小值是 7。
-
@RickJames 主要是我想不出一个直接的实现。我的人性化描述似乎并不能非常有效地转化为代码。
-
你能容忍多大的碰撞概率?
-
也许“哈希”是错误的术语; @Dave我不能容忍任何碰撞。每个排列都应该产生一个唯一的空间优化 ID。
-
我还发现了一个相关问题,这些问题被称为Lehmer Code
标签: c++ algorithm optimization