- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我上周学习了哈希表,但我想知道为哈希基选择什么是最好的值,以及我的哈希函数的表大小是多少,以便它以良好的时间复杂度运行。
这是我的哈希函数的代码:
h = 0
for i in range(len(key)):
h = (h * hashBase + ord(key[i])) % tableCapacity
return h
为什么选择 hashBase = 1 会增加哈希表操作的时间复杂度?为什么挑大tableCapacity比较好?另外,为什么 ie. hashBase = 250726 和 table capacity = 250727 导致其操作变慢?
最佳答案
tableCapacity
通常应与将散列到表中的键数保持合理比率。究竟什么比例取决于哈希冲突的处理方式——即:
将找到替代存储桶("open addressing" 又名“封闭哈希”):使用良好哈希函数,存储桶比键多 20-50%一个大致合理的范围
每个桶都包含一些在那里散列的元素链("separate chaining"):使用好的散列函数它无关紧要,所以你可以有一半的桶作为 key ,或者两倍的 key ,事情会很顺利,没有任何戏剧性的事情发生
也就是说,当散列函数不好,并且被散列的键的随机性不足以帮助散列函数充分执行时,有一个 tableCapacity
是有帮助的。减少冲突:尝试从被散列的键数和上面列出的比率派生的值附近的任何质数。例如,如果您有 6 个键并使用单独的链接,则 tableCapacity
5、7 或 11 是理智的。
但是,您的问题并未说明如何处理碰撞,因此我们将其留给您。
让我们继续考虑哈希逻辑本身:
h = (h * hashBase + ord(key[i])) % tableCapacity
这就像 this question 中描述的“MAD”哈希方法的简化/折衷形式- my answer 中有解释以后我假设您已经阅读过。
如果我们将您的函数与一般 MAD 形式进行对比,我们会发现您使用的是 % tableCapacity
在 key 的每个切片(字节?)上。在 python 中可能有意义的原因是 python 没有像许多低级语言(和 CPU 本身)那样溢出的固定位数的整数,所以如果你没有一些 %
循环内操作 h
value 可能会增长到与整个 key 相似的大小 - 如果您生成视频文件的哈希作为廉价校验和,那将非常缓慢并且浪费内存。所以,使用 %
限制多大h
可以在每次迭代之后得到理智,但由于其他答案中解释的原因,特别重要的是 tableCapacity
是质数,hashBase
应选择通常产生的值远大于 tableCapacity
尽量减少较早的哈希桶比后来的哈希桶更频繁地使用的数量(参见我上面链接的其他答案中的 200/255 示例)。
总结:选择一个大的伪随机 hashBase
- 说一个 32 位甚至 64 位的随机数,和一个素数 tableCapacity
考虑到您选择的开/关散列设计,与您的 key 数量成合理的比例。
Why does picking hashBase = 1 increase the time complexity of the hash table's operations?
hashBase
不应该很小 - 这意味着 key[i]
的贡献不太可能包装 h
%
之前绕过 table 很多次再次应用操作,失去了分散映射的所有好处。
Why is it better to pick a large tableCapacity?
好吧,更大的表意味着更多的桶 - 使用相同数量的键,冲突往往会更少,但通过适当的散列,您不需要过分。更多的桶意味着更多的内存使用和更少的缓存命中,这会减慢速度。
Also, why does ie. hashBase = 250726 and table capacity = 250727 cause its operations to slow down?
如上所述,您希望 hashBase 比表容量大得多。
关于python - 哈希基和表大小如何影响哈希的时间复杂度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56259064/
多数元素问题: Given an array of size n, find the majority element. The majority element is the element tha
我有一个简单的问题来找到数组 A 中的第一个唯一元素。但是,令我困扰的是使用不同方法的时间复杂度。到目前为止,我已经尝试过这两种方法。 第一种方法: LinkedHashMap> map = new
STL 中valarray::min 和valarray::max 函数的时间复杂度是多少? 此外,什么是查找各种其他 STL 组件的时间/空间复杂性的良好来源? 最佳答案 O(N) 这些函数不会缓存
我目前正在学习复杂性(或效率,不管你怎么调用它),我在我得到的一本书中读到了它。写了一些我觉得很无意义的东西,我需要一个解释。我试过在线查找,但我没有找到他们给出的这个特定示例的答案。 For an
如何分析算法?是什么让快速排序具有 O(n^2) 的最坏情况性能,而合并排序具有 O(n log(n)) 的最坏情况性能? 最佳答案 这是整个学期的主题。最终,我们讨论的是在算法完成之前必须完成的操作
有谁知道最流行的数据库的 SQL LIKE 运算符的复杂度是多少? 最佳答案 让我们分别考虑三个核心案例。此讨论是特定于 MySQL 的,但也可能适用于其他 DBMS,因为索引通常以类似的方式实现。
Go 编程语言中这个循环的计算复杂度是多少? var a []int for i := 0 ; i doublecap { newcap = cap } else {
我需要创建一个查找函数,其中 (X,Y) 对对应于特定的 Z 值。对此的一个主要要求是我需要尽可能接近 O(1) 复杂度。我的计划是使用 unordered_map。 我通常不使用哈希表进行查找,因为
快速提问,主要满足我对该主题的好奇心。 我正在编写一些带有 SQlite 数据库后端的大型 python 程序,并且将来会处理大量记录,因此我需要尽可能优化。 对于一些功能,我正在通过字典中的键进行搜
Go 编程语言中这个循环的计算复杂度是多少? var a []int for i := 0 ; i doublecap { newcap = cap } else {
我有这个方法: public static int what(String str, char start, char end) { int count=0; for(int i=0;
for (i = 0; i i; j--) //some code that yields O(1) } 我认为上面的代码会产生 n*log(n) 但我看到另一个消息来源说它真的是 n^2
我对 InnoDB 中 OFFSET 的复杂性有疑问。我知道这主要适用于线性复杂性,但如果我在字段上有索引?! 示例: CREATE TABLE `person_rand` ( `p_id` int
我嵌套了一些 if/else 语句,但我想减少它们的开销。 在示例中,我正在评估从哪个下拉列表中单击了 li 项目,以及该 li 项目是否是第一个 (currentIndex === 0)。 代码:
这是我的第一个问题,所以我希望我没有违反任何规则。我终于设法为基数排序算法编写代码,但我想知道我是否做错了。让我觉得我的算法看起来复杂度为 O(n^3),但众所周知,基数排序是一个 O(k.n) 算法
几周前我认识了 big-O 并试图掌握它,但是尽管有很多关于计算时间复杂度的 Material ,但我似乎无法找到如何使算法更高效。 我一直在练习 Codility 中的演示挑战: Write a f
在最近的一次考试中,我们得到了一个函数来计算在未排序的 ArrayList 中出现了多少个 double (不是原始 double,而是一个项目出现两次的次数)。 我正确地确定了 Big O 复杂度为
以下循环的大 O 复杂度是多少: for each vertex u ∈ C do for each vertex v ∈ C and v > u do 我在这里做的是想象以下集合 {
我想对条款进行排序,使每个条款都是下一个条款的大 O √n√logn √n log( n^30) n/〖(logn)〗^2 〖16〗^(log√n) 谁能帮忙找到顺序? 最佳答案 claim :16
我正在尝试计算此选择排序实现的大 O 时间复杂度: void selectionsort(int a[], int n) { int i, j, mini
我是一名优秀的程序员,十分优秀!