STL中的关联式容器比较及其常用接口测试:map、multimap、set、multiset
1. 关联式容器的异同点比较
- 共同点:
- 底层结构相同—红黑树
- 使用迭代器进行遍历:都是关于key有序的序列(遍历规则:中序插入/查找/删除----O(logN))
- value值可以重复
- 不同点:
- map:元素类型为K-V键值对,而且要求key一定要唯一
- multimap:元素类型为K-V键值对,key是可以重复的
- set:元素类型K,而且要求key必须要唯一,功能:元素去重&去重之后结果排序
- multiset:元素类型K, key可以重复,功能:元素不去重&结果排序
默认情况下,上述4中容器是按照less的方式进行比较,遍历完成之后可以得到关于key有序的升序序列,如果用户需要降序序列,则用户自己传递按照大于方式对元素进行比较(内置类型:greater,自定义类型用户自己实现比较器)
2. map常用接口测试
- map中内置的键值对类型是一个类模板pair<type,type> ,其内部实现是一个结构体,包含first和second两个成员变量,在map中first代表key值,second代表value值
#include<iostream>
#include<vld.h>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string, string>m;
m.insert(pair<string, string>("apple", "苹果"));//插入一个键值对
m.insert(pair<string, string>("orange", "橘子"));
m.insert(pair<string, string>("banana", "香蕉"));
cout << m.size() << endl;//map的键值对个数
cout << m["apple"] << endl;//重载的operator[],用于根据key值查找value的值
cout << m["banana"] << endl;
cout << endl;
// 注意:pair是一个类模板,里面有两个成员变量
// first : 键值对中的key
// second :键值对中的value
for (auto e : m)//遍历获得容器中的每一组元素
{
cout << "[" << e.first <<":"<< e.second <<"]"<<endl;
}
cout<<endl;
auto it = m.begin();
while (it != m.end())
{
cout << "[" << it->first << ":" << (*it).second << "]" << endl;
it++;
}
cout<<endl;
// map中的key必须要唯一
m.insert(make_pair("apple", "苹果"));
auto ret = m.find("orange");//根据key值查找value
if (ret != m.end())
{
cout << "[" << ret->first << ":" << ret->second << "]" << endl;
}
else
{
cout << "orange is not in map" << endl;
}
m.erase("orange");//删除某个键值对
ret = m.find("orange");
if (ret != m.end())
{
cout << "[" << ret->first << ":" << ret->second << "]" << endl;
}
else
{
cout << "orange is not in map" << endl;
}
m.clear();//清空整个容器中的元素
return 0;
}
- 应用:统计受喜爱的水果前三名
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vld.h>
#include<map>
#include<string>
#include<queue>
#include<vector>
using namespace std;
struct Comp
{
bool operator()(const pair<string,size_t> &left,const pair<string,size_t> &right)
{
return left.second < right.second;
}
};
int main()
{
string fruits[] = { "apple", "orange", "peach", "apple", "apple", "watermelen", "orange","banana", "banana", "apple", "orange", "apple", "banana" };
//1.统计各水果的投票个数
map<string, size_t> m;
for (auto e : fruits)
m[e]++;
//2.选出投票前三的水果
priority_queue<pair<string, size_t>, vector<pair<string, size_t>>, Comp> p;
for (auto e : m)
p.push(e);
//3.取出前三种水果的名字
vector<string> v;
for (size_t i = 0; i < 3; ++i)
{
v.push_back(p.top().first);
p.pop();
cout <<i+1<<":"<< v[i] << endl;
}
return 0;
}
2. multimap常用接口测试
- multimap中没有重载operator[ ]功能,因为它的key值可重复,所以不能返回唯一的value值,其余功能和map基本一致
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vld.h>
#include<map>
#include<string>
#include<queue>
#include<vector>
using namespace std;
int main()
{
multimap<string, string>m;
m.insert(pair<string, string>("apple", "苹果"));
m.insert(pair<string, string>("orange", "橘子"));
m.insert(pair<string, string>("banana", "香蕉"));
cout << m.size() << endl;
cout << endl;
// 注意:pair是一个类模板,里面有两个成员变量
// first : 键值对中的key
// second :键值对中的value
for (auto e : m)
{
cout << "[" << e.first << ":" << e.second << "]" << endl;
}
cout << endl;
auto it = m.begin();
// multimap中的key不需要唯一
m.insert(make_pair("apple", "富士山苹果"));
m.insert(make_pair("orange", "橙子"));
while (it != m.end())
{
cout << "[" << it->first << ":" << (*it).second << "]" << endl;
it++;
}
cout << endl;
auto ret = m.find("orange");
if (ret != m.end())
{
cout << "[" << ret->first << ":" << ret->second << "]" << endl;
}
else
{
cout << "orange is not in map" << endl;
}
m.erase("orange");
ret = m.find("orange");
if (ret != m.end())
{
cout << "[" << ret->first << ":" << ret->second << "]" << endl;
}
else
{
cout << "orange is not in map" << endl;
}
m.clear();
return 0;
}
3. set接口测试
- set中直接对key值进行排序,没有value值,在迭代插入元素时,会对元素进行去重和比较,从而得到一个去重后的有序表,其余接口功能大致一致
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vld.h>
#include<set>
using namespace std;
int main()
{
int array[] = { 2,2,3,3,1,1,0,0,9,9,5,5,8,8,6,6,4,4,7,7 };
set<int> s;
for (auto e : array)
s.insert(e);
for (auto e : s)
cout << e << " ";
cout << endl;
return 0;
}
4. multiset接口测试
- multiset和set的不同点在于,插入key值时不再去重,其余功能大致一致
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vld.h>
#include<set>
#include<functional>
using namespace std;
template<class T>//自定义模板类
struct Greater
{
bool operator()(const T& left, const T& right)const
{
return left > right;
}
};
int main()
{
int array[] = { 2, 2, 3, 3, 1, 1, 0, 0, 9, 9, 5, 5, 8, 8, 6, 6, 4, 4, 7, 7 };
multiset<int, Greater<int>> s(array, array + sizeof(array) / sizeof(array[0]));
cout << "降 序 :";
for (auto e : s)
cout << e << " ";
cout << endl;
multiset<int> p;
for (auto e : array)
p.insert(e);
cout << "升 序 :";
for (auto e : p)
cout << e << " ";
cout << endl;
return 0;
}