类型别名 | 说明 |
---|---|
key_type | 关键字类型,map的first或者set的元素 |
mapped_type | map中值类型 |
value_type | set为const key_type;map中为pair |
解引用一个关联迭代器,会得到类型为value_type的值引用。
#include
#include
#include
using namespace std;
int main()
{
map<string, int> word_count = { {"red",1},{"green",2},{"pipi",3}};
set<string> limit = { "the","a","an" };
auto beg1 = word_count.begin();
auto beg2 = limit.begin();
cout << beg1->first << " " << beg1->second << endl;
beg1++;
cout << beg1->first << " " << beg1->second << endl;
cout << *beg2 << endl;
beg2++;
cout << *beg2 << endl;
/*输出结果:green 2
pipi 3
a
an
*/
return 0;
}
虽然set类型同时定义了iterator 和const_ iterator 类型,但两种类型都只允许只读访问set中的元素。与不能改变-一个map元素的关键字一样,一个set中的关键字也是const的。可以用- 一个set迭代器来读取元素的值,但不能修改。
一般不在关联容器中应用泛型算法,实际应用一般作为源序列或目的位置。
最多常用的泛型算法仅有find,查询不修改重排内部的值,或者copy把关联容器当作复制的对象,复制到其他相关容器中。
使用insert函数插入,插入的方式有三种,一种是插入具体元素,一种是插入一个范围,还有一种是插入一段序列。
由于set内部的数据是不重复的,就算插入重复的,对于set来说只是自动去重而已,并不是很严重。
样例:
#include
#include
#include
#include
using namespace std;
int main()
{
vector<int> vec = { 1,1,2,2,3,4,5 };
set<int> set1, set2,set3;
set1.insert(vec[0]);
set2.insert(vec.begin(), vec. end());
set3.insert({ 1,1,2,2,3,4,5 });
cout << "set1:";
for (auto i : set1 )
{
cout << i << " ";
}
cout << endl<<"set2:";
for (auto i : set2)
{
cout << i << " ";
}
cout << endl << "set3:";
for (auto i : set3)
{
cout << i << " ";
}
return 0;
}
基本上是以下的四种写法:
stu.insert({ "qq",4 });
stu.insert(make_pair("aa",5 ));
stu.insert(pair<string,int>("bb", 6));
stu.insert(map<string, int>::value_type("cc", 7));
//args代表构造出一个与c所需要的类型一致的数据。
//插入单个值
//对于map和set,只有关键词不在c中时,才对容器进行插入操作。返回一个pair,指向具有指定在关键字元素的迭代器和插入是否成功的bool值。
//对于multimap和multiset,可以插入,返回指向新元素的迭代器。
> c.insert(v)
> c.emplace(args)
//p指出从哪里开始搜索新元素存储的位置。返回指向给定关键字元素的迭代器。
> c.insert(p,v)
> c.emplace(p,args)
//插入多个值,返回void
> c.insert(b,e)
> c.insert(il)
值得关注的是:
map元素再次插入即是修改其值。
#include
#include
using namespace std;
int main()
{
map<string, int> map1 = { {"张三",1},{"李四",2} };
map1.insert(make_pair("张三", 2));
cout << map1.begin()->second << endl;
//输出结果:2
return 0;
}
insert ( 或emplace)返回的值依赖于容器类型和参数。对于不包含重复关键字的容器(常指map和set),添加单一元素的insert 和emplace版本返回一个pair,告诉我们插入操作是否成功。pair的first成员是一个迭代器,指向具有给定关键字的元素;:second成员是一个bool值,指出元素是插入成功还是已经存在于容器中。如果关键字已在容器中,则insert什么事情也不做,且返回值中的bool部分为false. 如果关键字不存在,元素被插入容器中,且bool值为true。
auto j = stu.insert({ "qq",4 });
cout << "j "<<(j.first)->first << " " << (j.first)->second<< " " << j.second << endl; //j qq 4 1
auto k = stu.insert({ "qq",4 });
cout << "k " << (k.first)->first << " " << (k.first)->second << " " << k.second << endl; //k qq 4 0
//k和j的实际类型为:pair
计算字母出现次数:
string s;
cout << "input string:" << endl;
cin >> s;
map<char, int> lettertimes;
for (char a : s) {
//循环内可以修改为:++lettertimes.insert({a,0}).first->second;
auto p = lettertimes.insert({ a, 1 });
if (!p.second) {
++p.first->second;
}
}
for (auto i : lettertimes) {
cout << i.first << " " << i.second << endl;
}
++p.first->second;此句是重点,代表着实际上也就是对应字符的数字++
以multimap为例子吧:
multimap<string, string> vec;
//插入第一个元素 关键字为张三
vec.insert("张三", "李四");
//插入第二个元素,关键字仍然为张三
vec.insert("张三", "王五");
对允许重复关键字的容器,接受单个元素的insert操作返回一个指向新元素的迭代器。这里无须返回一个bool值,因为insert总是向这类容器中加入一个新元素。
c.erase(k) //删除关键词为k的元素,返回size_type值,即删除元素数量,返回0表示map中没有要删除元素
c.erase(p) //删除迭代器p处元素,返回p之后元素的迭代器,或c.end()
c.erase(b,e) //删除迭代器b~e范围元素,返回e
map和unordered_map提供了下标运算和对应at函数,当关键字不在map中时,下标操作会为该关键字创建元素并插入到map中,关联值可以被值初始化。
只可以对非const类型map进行下标操作。
set、multimap、unordered_multimap不支持下标运算。set中没有值对应关键字。multimap、unordered_multimap存在单关键字对多值。
//访问
cout << stu["hh"] << endl; //1
cout << stu.at("hh") << endl; //1
//插入并进行值初始化
stu["xh"] = 23;
cout << stu["xh"] << endl;
stu["hx"]; //值为0
对于顺序容器,解引用和下标运算返回类型一样。而对于map,下标操作返回mapped_type类型(返回的是值),而迭代器运算符返回的是value_type类型(关键字-值对)。
//不需要计数时使用find。需要计数使用count
c.find(k) //返回指向第一个关键字k元素的迭代器。k不在容器中时返回尾后迭代器
c.count(k) //返回关键字k数量
c.equal_range(k) //对于multimap和multiset,同关键字元素会相邻储存,通过此函数查找,返回迭代器pair,表示关键词等于k的元素范围。k不存在时,返回{c.end(),c.end()}。
//不适用于无序容器
c.lower_bound(k) //返回指向第一个不小于关键字k的元素的迭代器,指向第一个k
c.upper_bound(k) //返回指向第一个大于关键字k的元素的迭代器,指向最后一个k
小总结: