决定何时使用散列表

Deciding when to use a hash table

本文关键字:列表 何时使 决定      更新时间:2023-10-16

我正在解决一个具有以下要求的竞争性编程问题:

我必须维护一个2d唯一点(x,y)的列表,唯一点的数量将小于500。

我的想法是将它们存储在哈希表中(c++无序集是特定的),每次出现一个节点时,我都会查找表,如果节点不在那里,我将插入它。

我也知道一个事实,我不会做超过500查找。所以我看到了一些解决方案,简单地搜索数组(未排序),并检查节点在插入之前是否已经存在。

我的问题是,是否有任何合理的方法来猜测我什么时候应该使用哈希表来手动搜索键而不必对它们进行基准测试?

我的问题是,是否有任何合理的方法来猜测我什么时候应该使用哈希表来手动搜索键而不必对它们进行基准测试?

我猜你对基本算法很熟悉&时间复杂度和c++标准容器,并且知道哈希表访问是O(1)

如果哈希表代码(或一些平衡树代码,例如使用std::map -假设键上有一个简单的顺序)更具可读性,我更喜欢它,仅出于可读性原因。

否则,您可能会根据PC上各种操作的大致时间进行一些猜测。顺便说一句,整个http:///norvig.com/21-days.html页面值得一读。

基本上,内存访问比CPU中的其他操作要慢得多。CPU缓存非常重要。一个典型的需要从DRAM模块中获取数据的缓存错误的内存访问比一些基本的算术运算或机器指令(例如在寄存器中添加两个整数)要慢几百倍。

在实践中,这并不重要,只要你的数据很小(例如少于一千个元素),因为在这种情况下,它很可能位于二级缓存中。

在数组中(线性)搜索非常快(因为非常适合缓存),最多可以搜索数千个(小)元素。

IIRC, Herb Sutter在一些视频中提到,即使在向量中插入元素实际上(但不直观地)比将其插入到一些平衡树(或者可能是其他容器,例如哈希表)更快(考虑到移动片所需的时间),最多可容纳数千个小元素的容器大小。这是在典型的平板电脑、台式电脑或服务器微处理器上使用的,它们具有数兆字节的缓存。YMMV .

如果你真的那么在乎,你就不能避免基准测试。

请注意,500对整数可能适合L1缓存!

我的经验法则是假设处理器每秒可以处理10^9个操作。

在您的示例中,只有500个条目。一个0 (N^2)的算法是安全的。通过使用像vector这样的连续数据结构,您可以利用快速缓存命中。另外,哈希函数有时在常量方面是昂贵的。但是,如果您的数据大小为10^6,则安全复杂度可能总共只有O(N)。在这种情况下,您可能需要考虑为单个查找使用O(1) hashmap。

您可以使用大O复杂度来粗略估计性能。对于哈希表,在最坏的情况下,搜索一个元素的时间在O(1)到O(n)之间。这意味着,在最好的情况下,你的访问时间与映射中的元素数量无关,但在最坏的情况下,它与哈希表的大小线性相关。

二叉树保证搜索复杂度为O(nlog(n))。这意味着,搜索一个元素总是取决于数组的大小,但在最坏的情况下,它比哈希表快。

你可以在这个方便的网站上查找一些大O复杂度:http://bigocheatsheet.com/