set<string>::value_type v1; //这个v1是string类型
set<string>::key_type v2; //这个v2是string类型
map<string, int>::value_type v3; //v3是pair类型pair<const string, int>
map<string, int>::key_type v4; //v4是string类型
map<string, int>::mapped_type v5; //v5是int类型
11.3.1关联容器迭代器
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string, size_t> word_count;
string word;
while (cin >> word)
++word_count[word];
//获得指向word_count中的一个元素的迭代器
auto map_it = word_count.begin();
//*map_it是指向一个pair<const string, size_t>对象的引用
cout << map_it->first; //打印此元素的关键字
cout << " " << map_it->second; //打印此元素的值
// map_it->first="new key"; //错误:关键字是const的
++map_it->second; //正确:我们可以通过迭代器改变元素
return 0;
}
一个map是的value_type是一个pair,我们可以改变pair的值,但不能改变关键字成员的值。
set的迭代器是const
#include<iostream>
#include<set>
#include<string>
using namespace std;
int main()
{
//可以用一个set迭代器来读取元素的值,但不能修改
set<int> iset = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (set<int>::iterator set_it = iset.begin();
set_it != iset.end();++set_it)
{
//*set_it=42; //错误!!!
cout << *set_it<<" "; //正确:可以读关键字
}
cout << endl;
return 0;
}
遍历关联容器
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string, size_t> word_count;
string word;
while (cin >> word)
++word_count[word];
//获得指向word_count中的一个元素的迭代器
auto map_it = word_count.cbegin();
//比较当前迭代器和尾后迭代器
while (map_it != word_count.cend())
{
//解引用迭代器,打印关键字-值对
cout << map_it->first << " occurs "
<< map_it->second << " times " << endl;
++map_it; //递增迭代器,移动到下一个元素
}
return 0;
}
11.3.2添加元素
向set添加元素
vector<int> ivec={2,4,6,8,2,4,6,8}; //ivec有8个元素
set<int> set2; //空集合
set2.insert(ivec.cbegin(), ivec.cend()); //set2有4个元素
set2.insert({1,3,5,7,1,3,5,7}); //现在set2有8个元素
向map添加元素
//向word_count插入word的4种方法
word_count.insert({word, 1});
word_count.insert(make_pair(word, 1));
word_count.insert(pair<string, size_t>(word, 1));
word_count.insert(map<string, size_t>::value_type(word, 1));
检测insert的返回值
pair的first成员是一个迭代器,指向具有给定关键字的元素;second成员是一个bool值,指出元素是插入成功还是已经存放在于容器中。
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
cout << "请输入字母:" << endl;
//统计每个单词在输入中出现的次数
map<string, size_t> word_count;//string到size_t的空映射
string word;
while (cin >> word)
{
//插入一个元素,关键字等于word,值为1
//若word已在word_count中,insert什么也不做
auto ret = word_count.insert({ word, 1 });
if (!ret.second)
{
++ret.first->second; //递增计数器
}
}
for (const auto &w : word_count)//将map中的每个元素
//打印结果
cout << w.first << "出现了" << w.second << "次" << endl;
return 0;
}
- ret保存insert返回的值,是一个pair。
- ret.first是pair的第一个成员,是一个map迭代器,指向具有给定关键字的元素。
- ret.first->解引用此迭代器,提取map中的元素,元素也是一个pair。
- ret.first->second map中元素的值部分。
- ++ret.first->second递增此值。
向multiset或multimap添加元素
multimap<string, string> authors;
//插入第一个元素,关键字为Barth, John
authors.insert({"Barth, John", "Sot-Weed Factor"});
//正确:添加第二个元素,关键字也是Barth, John
authors.insert({"Barth, John", "Lost in the Funhouse"});
11.3.3删除元素
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<int, string> a;
multimap<int, string> ma;
// key键 value值
a.insert(map<int, string>::value_type(1,"One"));
a.insert(map<int, string>::value_type(2, "Two"));
a.insert(map<int, string>::value_type(3, "Three"));
a.insert(make_pair(-1, "Minus One"));
a.insert(pair<int, string>(1000, "One Thousand"));
a[1000000] = "One Million";
cout << "map里一共有" << a.size() << "个key-value数据" << endl;
cout << "这些数据是:" << endl;
map<int, string>::const_iterator i;
for (i = a.begin();i!=a.end();++i)
{
cout << "key:" << i->first;
cout << "Value:" << i->second.c_str();
cout << endl;
}
ma.insert(multimap<int, string>::value_type(3, "Three"));
ma.insert(multimap<int, string>::value_type(45, "Forty Five"));
ma.insert(make_pair(-1, "Minus One"));
ma.insert(pair<int, string>(1000, "One Thousand"));
ma.insert(pair<int, string>(1000, "One Thousand"));
cout << endl << "multimap里有" << ma.size() << "个数据." << endl;
multimap<int, string>::const_iterator im;
for (im = ma.begin(); im != ma.end();++im)
{
cout << "Key:" << im->first;
cout << "Value:" << im->second.c_str();
cout << endl;
}
cout << "multimap里有" << ma.count(1000) << "个1000." << endl;
if (ma.erase(-1) > 0)
cout << "删除-1成功" << endl;
multimap<int, string>::iterator iter = ma.find(45);
if (iter!=ma.end())
{
ma.erase(iter);
cout << "删除成功!" << endl;
}
ma.erase(ma.lower_bound(1000), ma.upper_bound(1000));
return 0;
}
11.3.4 map的下标操作
- map和unordered_map容器提供了下标运算符合一个对应的at函数。
- 对于一个map使用下标操作,其行为与数组或vector上的下标操作很不相同。
- 使用一个不在容器中的关键字作为下标,会添加一个此关键字的元素到map中。
set类型不支持下标。
与vector和string不同,map下标运算符返回的类型与解引用map迭代器得到的类型不同。
11.3.5 访问元素
set<int> iset={0,1,2,3,4,5,6,7,8,9};
iset.find(1); //返回一个迭代器,指向key==1的元素
iset.find(11); //返回一个迭代器,值指向iset.end()
iset.count(1); //返回1
iset.count(11); //返回0