为什么哈希表的哈希函数中的模数不够?
Why isn't modulus sufficient within a hash function for hash tables?
我经常看到或听到模数被用作散列的最后一步或散列之后。例如h(input)%N
其中 h
是散列函数,%
是取模运算符。如果我正在设计一个散列 table,并希望将一大组键映射到较小的 space 散列索引 table,模数运算符不能实现吗?此外,如果我想随机分布散列 table 中的那些位置,模数生成的余数是否不够?散列函数 h
在模数运算符之上提供什么?
I often see or hear of modulus being used as a last step of hashing or after hashing. e.g. h( input ) % N
where h
is the hash function and %
is the modulus operator.
确实如此。
If I am designing a hash table, and want to map a large set of keys to a smaller space of indices for the hash table, doesn't the modulus operator achieve that?
这正是模运算符的目的:限制数组索引的范围,所以是。
但是您不能简单地单独使用模运算符:模运算符需要一个整数值:您无法获得“字符串模数 N
”或“对象图模数 N
"[1].
Furthermore, if I wanted to randomize the distribution across those locations within the hash table, is the remainder generated by modulus not sufficient?
不,它不会——因为模运算符不会给你伪随机输出——它也没有任何类型的雪崩效应——这意味着相似的输入值会具有相似的输出哈希值,这将导致您的哈希表容器中出现 集群 ,这将导致性能不佳,因为哈希冲突的可能性大大增加(因此需要较慢的技术,如线性 -因为你失去了 O(1)
查找时间,所以探测破坏了哈希表的目的。
What does the hashing function h
provide on top of the modulus operator?
h
的域可以是任何东西,尤其是非整数值。
[1] 从技术上讲,如果您使用对象的内存地址值(即对象指针),这是可能的,但如果您的哈希表键不使用 对象标识,例如堆栈分配的对象或自定义struct
.
首先,哈希函数的主要目的是将不是数字的东西变成数字。即使您只是在那之后使用模数来获取范围内的数字,获取数字仍然是第一步,并且是哈希函数的责任。如果您正在散列整数并且您只是将整数用作它们自己的散列,那么并不是没有散列函数,而是您选择了恒等函数作为散列函数。如果你没有写出这个函数,那就意味着你内联了它。
其次,哈希函数可以提供更不可预测的分布以减少意外冲突的可能性。人们使用的数据通常包含模式,如果您只是使用带有模数的简单恒等函数,输入中的模式可能会使模数更容易引起冲突。散列函数提供了一个打破它的机会,因此模数不太可能暴露原始数据序列中的模式。
我经常看到或听到模数被用作散列的最后一步或散列之后。例如h(input)%N
其中 h
是散列函数,%
是取模运算符。如果我正在设计一个散列 table,并希望将一大组键映射到较小的 space 散列索引 table,模数运算符不能实现吗?此外,如果我想随机分布散列 table 中的那些位置,模数生成的余数是否不够?散列函数 h
在模数运算符之上提供什么?
I often see or hear of modulus being used as a last step of hashing or after hashing. e.g.
h( input ) % N
whereh
is the hash function and%
is the modulus operator.
确实如此。
If I am designing a hash table, and want to map a large set of keys to a smaller space of indices for the hash table, doesn't the modulus operator achieve that?
这正是模运算符的目的:限制数组索引的范围,所以是。
但是您不能简单地单独使用模运算符:模运算符需要一个整数值:您无法获得“字符串模数 N
”或“对象图模数 N
"[1].
Furthermore, if I wanted to randomize the distribution across those locations within the hash table, is the remainder generated by modulus not sufficient?
不,它不会——因为模运算符不会给你伪随机输出——它也没有任何类型的雪崩效应——这意味着相似的输入值会具有相似的输出哈希值,这将导致您的哈希表容器中出现 集群 ,这将导致性能不佳,因为哈希冲突的可能性大大增加(因此需要较慢的技术,如线性 -因为你失去了 O(1)
查找时间,所以探测破坏了哈希表的目的。
What does the hashing function
h
provide on top of the modulus operator?
h
的域可以是任何东西,尤其是非整数值。
[1] 从技术上讲,如果您使用对象的内存地址值(即对象指针),这是可能的,但如果您的哈希表键不使用 对象标识,例如堆栈分配的对象或自定义struct
.
首先,哈希函数的主要目的是将不是数字的东西变成数字。即使您只是在那之后使用模数来获取范围内的数字,获取数字仍然是第一步,并且是哈希函数的责任。如果您正在散列整数并且您只是将整数用作它们自己的散列,那么并不是没有散列函数,而是您选择了恒等函数作为散列函数。如果你没有写出这个函数,那就意味着你内联了它。
其次,哈希函数可以提供更不可预测的分布以减少意外冲突的可能性。人们使用的数据通常包含模式,如果您只是使用带有模数的简单恒等函数,输入中的模式可能会使模数更容易引起冲突。散列函数提供了一个打破它的机会,因此模数不太可能暴露原始数据序列中的模式。