关联容器和顺序容器的区别:
关联容器通过关键字来保存和访问;顺序容器按照在容器中的位置保存和访问。关联容器不支持顺序访问!(实践的时候才知道写了个超搓的代码。。)
情形:求一个Top K的问题。给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2]
我先建立一个哈希表,记录了每个元素出现的次数,然后我想根据出现次数,来取出前面K个元素。。。汗!
unordered_map<int,int> hash_table;
for(auto item : nums) hash_table[item]++;
//哈希表是关联容器的。。。怎么能这样访问呢!
for(int i =0;i<hash_table.size();i++){
hash_table[i]...
}
tips:
- map:元素是key-value对(pair)。每个pair对有first和second两个元素。
- set:元素是关键字key。
- mutil表示允许关键字重复,如mutilset,mutilmap。
- unordered表示允许元素无序保存,如unordered_set,unordered_map。
- 没有重复元素是set和map的特点,举例:可以把一个字符串中不同的元素提取出来。
所包含的头文件
- map和mutilmap定义在头文件map中;
- set和multiset在头文件set中;
- 无序容器则定义在头文件unordered_set,unordered_map中。
- pair类型定义在头文件utility中。
添加:
和顺序容器的push_back不同,这里只能使用insert。最简单的初始化pair对的方法“使用{}列表初始化”。因为set和map包含不重复关键字,所以插入一个已存在的关键字没有影响。
//向map中添加元素
map<string,int> my_map;
my_map.insert({"qqaz",2});
//向set中添加元素
set<int> my_set;
my_set.insert({1});
//mutilset,mutilset一样就不再多写了。
删除元素:
set<string> name_vec{"mary","tub","wwqh","wsz"};
auto head = name_vec.begin();
auto tail= name_vec.end();
//1、按照关键字删除
name_vec.erase("mary");
//2a、按照迭代器删除
name_vec.erase(head);
//2b、按照迭代器删除范围
name_vec.erase(head,tail);
下标操作:
set只有关键字,不支持下标操作;map支持下标操作,特别的是:当关键字不在map中,它会创建一个元素并插入到map中,关联值将进行值初始化。
map<string,int> c;
//[]如果没有这个元素会插入
c["zzz"]...
//at,带参数检查,如果没有会跑出一个out_of_range
c.at("zzz")...
访问元素(查找):
使用count,返回的是被查找元素的个数。如果有,返回1;否则,返回0。注意,map中不存在相同元素,所以返回值只能是1或0。
if(hash_table.count(other) && hash_table[other] != i)
使用find,返回的是被查找元素的位置,没有则返回map.end()。
if(hash_table.find(other) !=hash_table.end() && hash_table[other] != i)
无序容器:
维护元素有序的代价是非常高
map与unordered_map相比:
map底层实现为红黑数,undered_map底层实现为哈希表,两者均不能有重复的建,均支持[]运算符
map与multimap相比:
两者底层实现均为红黑树,但是multimap支持重复的键,不支持[]运算符