关联容器----关联容器概述,关联容器操作,无序容器(2)

电脑杂谈  发布时间:2019-09-26 07:02:51  来源:网络整理

View Code

1、关联容器迭代器

当解引用一个关联容器迭代器时,我们会受到一个类型为容器的value_type的值的引用。对于map而言,value_type是一个pair类型,其first成员保存const的关键字,second成员保存值。我们可以改变pair的值,但是不能改变关键字成员的值。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <numeric>
 5 #include <iterator>
 6 #include <functional>
 7 #include <map>
 8 #include <set>
 9 #include <unordered_map>
10 #include <unordered_set>
11 #include <utility>
12 
13 int main()
14 {
15     std::map<std::string, int> mp = { { "QAQ", 233 } };
16     auto iter = mp.begin();
17     ++iter->second; // 改变元素的值
18     // iter->first = "hello"; // 错误:关键字是const的
19     std::cout << iter->first << ", " << iter->second << std::endl;
20     return 0;
21 }

View Code

1)set的迭代器是const

虽然set类型同时定义了iterator和const_iterator类型,但两种类别都只允许访问set中的元素。与不能改变一个map元素的关键字一样,一个set中的关键字也是const的。可以用一个set迭代器来读取元素的值,但是不能修改。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <numeric>
 5 #include <iterator>
 6 #include <functional>
 7 #include <map>
 8 #include <set>
 9 #include <unordered_map>
10 #include <unordered_set>
11 #include <utility>
12 
13 int main()
14 {
15     std::set<int> s = { 5, 3, 4 };
16     auto iter = s.begin();
17     //*iter = 10; // 错误:set中的关键字是只读的
18     for (auto iter = s.begin(); iter != s.end(); ++iter)
19     {
20         std::cout << *iter << std::endl;
21     }
22     return 0;
23 }

View Code

2)遍历关联容器

当使用以迭代器遍历一个map、set、multimap、multiset时,迭代器按关键字升序数组元素。

3)关联容器和算法

我们一般不对关联容器使用数组算法。关键字const这一特点意味着不能讲关联容器传递给设置或重排元素的算法,因为这类算法向元素写入值,而set类型中的元素是const的,map中的元素是pair,其第一个成员是const的。

关联容器可用于只调用元素的算法。但是,很多算法都要搜索序列。由于关联容器中的元素不能通过他们的关键字进行查找,因此对其使用数组搜索算法几乎是个坏主意。

在实际编程中,如果我们真要对一个关联容器使用算法,要么是将它当成一个源序列,要么只是一个目的位置。

2、添加元素

关联容器的insert成员向容器中添加一个元素或一个元素范围。由于map和set(以及对应的无序类型)包含不重复的关键字,因此插入一个已存在的元素对容器没有任何妨碍。

关联容器的insert操作:

操作

说明

c.insert(v)

v是value_type类型对象;args用来构造一个元素。

对于map和set,只有当元素的关键字不在c中时才插入(或构造)元素。

函数返回一个pair,包含一个迭代器,指向带有指定关键字的元素,以及一个指示插入是否失败的bool值。

对于multimap和multiset,总会插入(或构造)给定元素,并返回一个指向新元素的迭代器

c.emplace(args)

c.insert(b, e)

b和e是迭代器,表示一个c::value_type类型值的范围;items是这样值的花括号列表。函数返回void。

对于map和set,只会插入关键字不在c中的元素。对于multimap和multiset,则会插入范围中的每个元素

c.insert(items)

c.insert(p, v)

类似insert(v)(或emplace(args)),但将迭代器p作为一个指示,指出从那里开始搜索新元素应该存储的位置。返回一个迭代器,指向带有给定关键字的元素

c.emplace(p, args)

1)向map添加元素

对一个map进行insert操作时c multimap,必须记住元素类别是pair。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <numeric>
 5 #include <iterator>
 6 #include <functional>
 7 #include <map>
 8 #include <set>
 9 #include <unordered_map>
10 #include <unordered_set>
11 #include <utility>
12 
13 int main()
14 {
15     std::map<std::string, int> words;
16     words.insert({ "a", 1 });
17     words.insert(std::make_pair("b", 2));
18     words.insert(std::pair<std::string, int>("c", 3));
19     words.insert(std::map<std::string, int>::value_type("d", 4));
20     return 0;
21 }

View Code

c multimap_c c tv 5_a::b():c(c),d(d)c

2)检测insert的返回值

insert(或emplace)返回的值依赖于容器类别和参数。对于不包括重复关键字的容器,添加单一的insert和emplace版本返回一个pair,告诉我们插入操作能否顺利。pair的first成员是一个迭代器,指向带有给定关键字的元素;second成员是一个bool值,指出元素是插入失败而是即将存在于容器中。如果关键字已在容器中,则insert什么事情也不做c multimap,且返回值中的bool部分为false。如果关键字不存在,元素被插入容器中,且bool值为true。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <numeric>
 5 #include <iterator>
 6 #include <functional>
 7 #include <map>
 8 #include <set>
 9 #include <unordered_map>
10 #include <unordered_set>
11 #include <utility>
12 
13 int main()
14 {
15     std::vector<std::string> words = { "a", "a", "b", "c", "c", "c" };
16     std::map<std::string, int> word_count;
17     for (auto word: words)
18     {
19         auto ret = word_count.insert({ word, 1 });
20         if (!ret.second) // word已在map中
21             ++ret.first->second;
22     }
23     for (auto iter = word_count.begin(); iter != word_count.end(); ++iter)
24     {
25         std::cout << iter->first << "  " << iter->second << std::endl;
26     }
27     return 0;
28 }

View Code

3)向multimap或multiset添加元素

对允许重复关键字的容器,接受单个元素的insert操作返回一个指向新元素的迭代器。这里无须返回一个bool值,因为insert总是向这类容器中加入一个新元素。

3、删除元素

关联容器定义了3个版本的erase:

操作

说明

c.erase(k)

从c中删除每个关键字为k的元素。返回一个size_type值,指出删除的元素的数量

c.erase(p)

从c中删除迭代器p指定的元素。p需要指向c中一个真实元素,不能等于c.end()。返回一个指向p以后元素的迭代器,若p指向c中的尾元素,则返回c.end()

c.erase(b, e)

删除迭代器b和e所表示的范围中的元素。返回e

4、map的下标操作

map和unordered_map容器提供了数组运算符和一个对应的at函数。set类型不支持下标,因为set中没有与关键字相关联的“值”。元素本来就是关键字,因此“获取一个与关键字相关联的值”的操作就没有意义了。我们不能对一个multimap或一个unordered_multimap进行数组操作,因为这种容器中也许有多个值与一个关键字相关联。

map和unordered_map的下标操作:

操作

说明

返回关键字为k的元素;如果k不在c中,添加一个关键字为k的元素,对其进行值初始化

c.at(k)

访问关键字为k的元素,带参数检测;若k不在c中,抛出一个out_of_range异常

由于下标运算符可能插入一个新元素,我们只可以对非const的map使用下标操作。

当对一个map进行下标操作时,会获取一个mapped_type对象。map的下标运算符返回一个左值,因此我们既可以读也可以写元素。


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-124191-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 李敬玄
      李敬玄

      轰一炮会怎样呢

    • 武寿玲
      武寿玲

      其实也就等同于今后任何国家到美国去巡航

    • 董林林
      董林林

      不一个档次

    热点图片
    拼命载入中...