决定何时使用散列表
Deciding when to use a hash table
我正在解决一个具有以下要求的竞争性编程问题:
我必须维护一个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/
- C++:如何使函数只返回作为列表一部分的字符串
- 何时使函数成为类成员函数C++?
- 如何在C / C++中正确实现链接列表而不会使程序崩溃
- 最大数量.给定一个非负整数列表,排列它们以使它们形成最大的数字
- 我怎样才能使这个列表工作
- gRPC trace.cc 的方法 TraceFlagList::Add(TraceFlag* flag) 使其链接列表
- 何时必须使操作员<<过载?
- 如何创建一个向量,使每个框都是链列表的头部
- 我如何使我的循环转到char*阵列的尽头,并将每个城市都放在链接的列表中(城市被划分为白色的空间)
- 当将 getline 与 int 一起使用时,如何修复"没有重载函数 'getline' 的实例与参数列表匹配"
- 如何使QComboBox的文本加粗,而不是列表项?
- 在Windows上,何时有必要将附加到目录路径上,以使_stat成功
- 如何使gotoxy()函数在光标所在的链接列表中选择节点
- 将元素添加到列表会使程序崩溃..有时
- 如何使可变 lambda 捕获列表的某些成员变得非常量
- 在类中使用时,lambda 捕获列表中的 [this] 和 [&] 是否等效?
- 使用成员初始值设定项列表会使初始化速度稍快
- 如何使此链接列表正常工作
- 使初始化列表与 C++ 中的继承一起使用
- 复制链接列表会使程序崩溃