关联容器是使用关键字来保存和访问元素的。
有序关联容器是按顺序存储元素的集合。
map:关联数组,保存 关键字--值 对
set:关键值就是值,即只保存关键字的容器
multimap:关键字可以重复出现的map
multiset:关键字可以重复出现的set
cout << "================map==============" << endl;
map<key,value>, map的key只能出现一次,
要定义key和value的类型,比如map<string,string> 为key和value都是string类型
map<string, size_t> word_count;
string word;
while (cin >> word)
{
++word_count[word];
}
for (const auto & w : word_count)
{
cout << w.first << " occurs " << w.second << ((w.second > 1) ? "times" : "time") << endl;
}
cout << "=================set=================" << endl;
set<key>, set只有关键字,而且key也只能出现一次,要定义key的类型,如set<int>,key为int类型
set<string> exclude;
exclude = { "aaa","bbb","ggg","ggg", "ccc" };
for (const auto &ex : exclude)
{
cout << ex << " ";
}
cout << endl;
cout << "=================multimap和multiset=================" << endl;
multimap:key可以重复出现的map,使用方式和map相同
multiset:key可以重复的set,使用方式和set相同
multimap<string, string> strmult;//键和值都是string类型的multimap
multiset<vector<int>> muvecset;//键是vector<int>类型的
cout << "=================pair=================" << endl;
pair定义在头文件utility中,保存两个数据,类似容器,是一个用来生成特定类型的模版,两个数据成员分别为first和second,map中的类型就是pair。
make_pair:可以用来生成pair,pair的两个类型来自于make_pair的参数make_pair(a,b);
pair<string, int> psi;
psi = { "aaa",3 };
cout << psi.first << " " << psi.second << endl;
psi = make_pair("bbb",4);
cout << psi.first << " " << psi.second << endl;
cout << "=================操作=================" << endl;
key_type:此容器类型的关键字类型
mapped_type:每个关键字关联的类型,只适用于map
vale_tupe:对于set,与key_type一样。对于map,为pair<const key_type,mapped_type>
//添加元素
Insert:对于map和set来说只有关键字不存在时才能操作成功,并返回迭代器。对于无序的可以插入成功,并返回迭代器
insert的返回值依赖于容器类型和参数,对于不重复关键字的容器,返回的是一个pair,其中的first是一个迭代器,second是一个bool值,表示是否成功。
emplace:构造容器中的一个元素
因为map中的类型可以是pair,所以向map中添加元素时,可以使用pair及其创建
map<string, int> map1;
map1.insert({ "aaa",1 });
map1.insert(make_pair("bbb", 2));
map1.insert(pair<string, int>("ccc", 3));
map1.insert(map<string, int>::value_type("ddd", 4));
for (const auto& w : map1)
{
cout << w.first << " " << w.second << endl;
}
vector<int> ivec = { 2,4,6,8,3,5,7,4,8 };
set<int> set1;
set1.insert(ivec.begin(), ivec.end());//使用迭代器范围添加
set1.insert({ 1,3,5,6,8,9 });
for (const auto& ex : set1)
{
cout << ex << " ";
}
cout << endl;
multimap、multiset的元素添加和map、set一样,只是添加重复key的时候可以成功
multimap<string, int> mulsmp;
mulsmp.insert(make_pair("bbb", 2));
mulsmp.insert(make_pair("bbb", 3));
for (const auto& w : mulsmp)
{
cout << w.first << " " << w.second << endl;
}
multiset<int> muliset;
muliset.insert(ivec.begin(), ivec.end());
for (const auto& ex : muliset)
{
cout << ex << " ";
}
cout << endl;
insert返回
auto ipa1 = map1.insert({ "aaa",2 });
不允许重复的容器,会返回一个pair,这个pair的第一个类型为容器定义的类型的迭代器。第二个类型就是一个bool值,用来判断是否插入成功
cout << ipa1.first->first << endl;//返回一个map迭代器的类型,返回的是存在key值的迭代器,因为是map类型,通过first,second来使用。所以ipa1.first->first为key值
cout << ipa1.first->second << endl;//为value值,
cout << ipa1.second << endl;//插入失败
set<string> stins = { "bbb","aaa","ccc" };
auto ispa = stins.insert("ccc");
cout << *ispa.first << endl;//set类型的迭代器,因为类型为string类型的迭代器,所以要解引用
cout << ispa.second << endl;//插入失败,一个bool值
auto ispa1 = stins.insert("ddd");//插入成功
cout << *ispa1.first << endl;
auto ipa2 = mulsmp.insert(make_pair("bbb", 3));
auto ipaset2 = muliset.insert(777);
允许重复的容器的返回类型只是一个容器的迭代器,因为可以重复所以不用返回bool值来表示是否插入成功。
cout << ipa2->first << endl;
cout << ipa2->second << endl;
cout << *ipaset2 << endl;//int型的迭代器
删除元素
erase:参数可以是关键字,可以是指针,可以是范围。
对于不重复的容器返回0或1,对于重复的容器返回值可能大于1。返回值为删除数量
stins.erase("aaa");
map的下标操作
map有下标操作:[k]、at(k) 类似数组,返回存放的值,[]会对不存在的关键字初始化
map下标运算符返回的类型为mapped_type
cout << map1["aaa"] << endl;
cout << "===================访问元素=====================" << endl;
find:返回一个迭代器,指向第一个关键字为k的元素,若k不存在,返回尾后迭代器
count:返回关键字等于k的元素数量,对于不允许重复关键字的容器,返回1或0
lower_bound:返回一个迭代器,指向第一个关键字不小于k的元素
upper_bound:返回一个迭代器,指向第一个关键字大于k的元素
equal_range:返回一个迭代器pair,表示关键字等于k的元素的范围。若k不存在,pair的两个成员均等于end()。
set<int> iset = { 0,1,2,3,4,5,6,7,8,9 };
cout << *iset.find(4) << endl;
cout << iset.count(4) << endl;
multiset<int> imulset = { 1,2,3,4,5,5,4,3,5,6,7,2 };
cout << *imulset.find(5) << endl;
cout << imulset.count(5) << endl;
auto ipmset = imulset.equal_range(5);
cout << *ipmset.first << " " << *ipmset.second << endl;