9月7号下午写题(The Preliminary Contest for ICPC Asia Xuzhou 2019)遇到这个so easy ,我用了map写一直超时,想了底层map的查找没有hash_map快,然后就用了hash_map也超时了,后来看题解是用的unordered_map可以过。就让我疯狂测试了一波什么情况下超时。(????9月8号我又测试了一波,发现!!!!????我昨天比赛交的超时代码也能在oj上过了??我???????【小小的脸上大大的疑惑???】)
9月7号的测试结果让我以为:
!List.count(x) 和 !List[x] ,List[x]==0的效率不一样 。因为我测试了一下。后两者都超时了。
理一下吧测试结果:
unordered_map : !List.count(x) WA? !List[x] AC(3)/TLE(3) List[x]==0 AC(3)/TLE(4)
hash_map : !List.count(x) WA? !List[x] AC(4) List[x]==0 AC(4)
map: !List.count(x) WA? !List[x] TLE(1) List[x]==0 TLE(1)
使用的模板是下面一套:(也是我比赛时候交的写法!!!一毛一样 ,我测的时候改的只有hash_map 和unordered_map,然后条件改改) 今天测我超时的写法四次都过了,我比赛的时候是什么“好运气”,不过测过来还真的看运气。
在看一下后来看群里发的解题写法,主函数逻辑这里不太一样,应该是影响了count。
unordered_map : !List.count(x) AC(3) !List[x] TLE(5)/AC(2) List[x]==0 TLE(2)/AC(2)
hash_map : !List.count(x) AC(2) !List[x] AC(2) List[x]==0 AC(3)
map: !List.count(x) TLE(2) !List[x] TLE(1) List[x]==0 TLE(1)
还是只有hash_map 和unordered_map,然后条件改改.
总之这个题目过的看几率,但是这些肯定要从他们的低层原理说起。
STL中,map
对应的数据结构是 红黑树。红黑树是一种近似于平衡的二叉查找树,里面的数据是有序的。在红黑树上做查找操作的时间复杂度为 O(logN)。而 unordered_map
对应 哈希表,哈希表的特点就是查找效率高,时间复杂度为常数级别 O(1), 而额外空间复杂度则要高出许多。所以对于需要高效率查询的情况,使用 unordered_map
容器。而如果对内存大小比较敏感或者数据存储要求有序的话,则可以用 map
容器。
所以只是用到查找功能用unordered_map 和 hash_map
关于hash_map 和 unordered_map:
由于在C++标准库中没有定义散列表hash_map,标准库的不同实现者将提供一个通常名为hash_map的非标准散列表。因为这些实现不是遵循标准编写的,所以它们在功能和性能保证上都有微妙的差别。
从C++11开始,哈希表实现已添加到C++标准库标准。决定对类使用备用名称,以防止与这些非标准实现的冲突,并防止在其代码中有hash_table的开发人员无意中使用新类。
所选择的备用名称是unordered_map,它更具描述性,因为它暗示了类的映射接口和其元素的无序性质。
可见hash_map , unordered_map本质是一样的,只不过 unordered_map被纳入了C++标准库标准。
参考链接
【2】https://www.sczyh30.com/posts/C-C/cpp-stl-hashmap/