关联式容器的共性:set<Key> multiset<Key> map<Key, Val> multimap<Key, Val>
- 关联式容器都是用二叉查找树来实现的,都会自动依据关键值排序
- 查找:find(key) 返回指向结果的迭代器,失败返回.end()
- 统计:conunt(key) 统计,关键字等于元素的个数
- 删除:erase(key) 删除关键字等于 key的所有元素
- 区间:lower_bound(key) upper_bound(key) 关键字为key元素的区间 equal_range(key) 一次取得关键字为key的区间。返回一个pair
- 插入:插入元素不用指定位置,因为是查找树 insert(element)
- 构造函数:可以用比较函数作为参数,返回bool(*compare)(T a, T b) 默认使用小于符号
| map | multimap | set | multiset |
元素 | (key\val)对 | (key\val)对 | key | key |
K重复 | 不允许 | 允许 | 不允许 | 允许 |
操作 | 可以用k为下标 |
|
|
|
共性部分
#include <iostream>
#include <set>
#include <algorithm>
#include <string>
#include <exception>
#include <cassert>
using namespace std;
template <typename T>
void print(T b, T e, string s = "; "){
while(b!=e) {
cout << *b++ << s;
}
cout << endl;
}
struct Person {
string name;
int age;
public:
Person(string name, int age):name(name), age(age){}
};
bool operator < (const Person& p1, const Person& p2){
//return p1.age < p2.age;
return p1.age<p2.age || p1.age==p2.age && p1.name < p2.name;
}
ostream& operator << (ostream& o, const Person& p){
return o << p.name << "; " << p.age << " ";
}
int main(){
multiset<Person> mp;
mp.insert(Person("wym", 20));
mp.insert(Person("abc", 25));
mp.insert(Person("gjt", 16));
mp.insert(Person("wmq", 23));
mp.insert(Person("pce", 45));
mp.insert(Person("opn", 20));
mp.insert(Person("nbr", 20));
mp.insert(Person("wym", 20));
mp.insert(Person("wym", 20));
mp.insert(Person("lkh", 20));
print(mp.begin(), mp.end());
//查找比对是按照年龄来处理的,上面写过算法
multiset<Person>::iterator ite = mp.find(Person("ppp", 20));
if(ite == mp.end()){
cout << "meizhaodao" << endl;
} else {
cout << "faxianmubiao " << *ite << endl;
}
//找到指定对象,这里的查找依托于重载的比较函数
ite = mp.find(Person("wym", 20));
cout << mp.count(*ite) << " " << *ite << endl;
//找到指定对象序列的首末位置
//注意,这里输出的只有指定对象,并不是原序列的首末位置
multiset<Person>::iterator ib, ie;
ib = mp.lower_bound(Person("wym", 20));
ie = mp.upper_bound(Person("wym", 20));
print(ib, ie);
//删除,这里是删除了所有的指定对象
mp.erase(Person("wym", 20));
print(mp.begin(), mp.end());
getchar();
return 0;
};
Map的个性
- 不允许重复的key
- 每个元素是(key\val)对
- 支持以key为下标取得访问对应的val数据,如果key不存在插入一个新的(key\val)对,用零初始化初时val。
#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#include <exception>
#include <cassert>
using namespace std;
template <typename T>
void print(T b, T e, string s = "; "){
while(b!=e) {
cout << *b++ << s;
}
cout << endl;
}
//map里面是pair类型,需要重载输出运算符
template <typename K, typename V>
ostream& operator << (ostream& o, const pair<K, V>& p){
return o << p.first << ": " << p.second << " ";
}
int main(){
//插入数据
map<int, string> mis;
mis.insert(pair<int, string>(18, "wym"));
mis.insert(make_pair(12, "wym"));//这个是用函数自动初始化类模板
mis.insert(map<int, string>::value_type(15, "zyl"));//内部类型的初始化模板
mis[13] = "ytr";//通过下标插入数据
print(mis.begin(), mis.end());
//修改
mis[13] = "xiugai";
print(mis.begin(), mis.end());
getchar();
return 0;
};
Multimap的个性
- 允许重复key
- 不支持[]运算
- 每个元素是(key\val)对
#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#include <exception>
#include <cassert>
using namespace std;
template <typename T>
void print(T b, T e, string s = "; "){
while(b!=e) {
cout << *b++ << s;
}
cout << endl;
}
//map里面是pair类型,需要重载输出运算符
template <typename K, typename V>
ostream& operator << (ostream& o, const pair<K, V>& p){
return o << p.first << ": " << p.second << " ";
}
int main(){
//插入数据
typedef multimap<string, double> MSD;
MSD m;
m.insert(MSD::value_type("kkq", 2500));
m.insert(MSD::value_type("kkq", 2600));
m.insert(make_pair("asd", 2600));
m.insert(make_pair("ope", 2600));
print(m.begin(), m.end());
MSD::iterator ib = m.begin(), ie;
MSD cnt;
while(ib!=m.end()){
string name = ib->first;
ie = m.upper_bound(name);
double sum = 0.0;
while(ib!=ie){
sum += ib++->second;
}
cnt.insert(make_pair(name, sum));
}
print(cnt.begin(), cnt.end());
getchar();
return 0;
};
Set的个性
- 元素就是key
- 不允许重复key
#include <iostream>
#include <set>
#include <algorithm>
#include <string>
#include <exception>
#include <cassert>
using namespace std;
template <typename T>
void print(T b, T e, string s = "; "){
while(b!=e) {
cout << *b++ << s;
}
cout << endl;
}
int main(){
//插入数据,重复数据不会显示
set<string> ss;
ss.insert("dds");
ss.insert("qwe");
ss.insert("opi");
ss.insert("qwe");
print(ss.begin(), ss.end());
getchar();
return 0;
};
Multiset 的个性
- 允许重复
#include <iostream>
#include <set>
#include <algorithm>
#include <string>
#include <exception>
#include <cassert>
using namespace std;
template <typename T>
void print(T b, T e, string s = "; "){
while(b!=e) {
cout << *b++ << s;
}
cout << endl;
}
int main(){
//插入数据,重复数据会显示
multiset<string> ss;
ss.insert("dds");
ss.insert("qwe");
ss.insert("opi");
ss.insert("qwe");
print(ss.begin(), ss.end());
getchar();
return 0;
};