【C++Primer】第11章 关联容器

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 【C++Primer】第11章 关联容器

第11章 关联容器


关联容器按关键字来保存和访问;与顺序容器不同



11.1 使用关联容器


map<string, size_t> word_count;
string word;
while(cin >> word){
    ++word_count[word];
}
for(const auto& w : word_count){
    cout << w.first << "出现" << w.second << "次" << endl;
}


11.2 关联容器概述


关联容器的迭代器都是双向的


11.2.1 定义关联容器


map<string, size_t> word_count;
set<string> exclude = {"the", "but", "and", "or"};  //列表初始化
map<string, string> authors = {
    {"Joyce", "James"},
    {"Austen", "Jane"},
    {"Dickens", "Charles"}
};


vector<int> ivec = {1,1,2,2,3,3,4,4};
set<int> iset(ivec.cbegin(), ivec.cend());
set<int> miset(ivec.cbegin(), ivec.cend());
cout << ivec.size() << endl;   //8
cout << iset.size() << endl;   //4
cout << miset.size() << endl;  //8


11.2.3 pair类型


pair<string string> a;
pair<string, size_t> b;
pair<string, vector<int>> line;
pair<string, string> author{"James", "Jotces"};  //初始化



11.3 关联容器操作



set<string>::value_type v1;       //string
set<string>::key_type v2;         //string
map<string, int>::value_type v3;  //pair<const string, int>
map<string, int>::key_type v4;    //string
map<string, int>::mapped_type v5;  //int


11.3.1 关联容器迭代器



我们通常不能对关联容器使用泛型算法


set类型中元素是const的


map中的元素是pair,其第一个成员是是const的


使用关联容器定义的专用find成员会比调用泛型find快得多


练习11.16


map<string, string>family;
map<const string, string>::iterator it;
it->first = "AAA";  //错误,const类型
it->second = "BBB";


练习11.17


v是一个string的vector,c是一个string的muitiset


copy(v.begin(), v.end(), inserter(c, c.end()));
copy(v.begin(), v.end(), back_inserter(c));   //错误, back_inserter创建一个使用push_back的迭代器
copy(c.begin(), c.end(), inserter(v, v.end()));
copy(c.begin(), c.end(), back_inserter(v));


练习11.18


pair<const string, size_t>::iterator map_it;


11.3.2 添加元素


set两种方式添加元素:


  • 一对迭代器


  • 列表初始化


vector<int> ivec = {2,4,6,8,2,4,6,8};
set<int> set2;
set2.insert(ivec.cbegin(), ivec.cend());  //4个元素
set2.insert({1,3,5,7,1,3,5,7});           //8个元素


map添加元素:


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));



11.3.3 删除元素


关联容器提供一个额外的erase操作,它接受一个key_type参数。此版本删除所有匹配给定关键字的元素


对允许重复关键字的容器,删除元素的数量可能大于1


multimap<string, string> authors;
authors.insert({"Barth, John", "Sot"});
suthors.insert({"Barth, John", "Lost"});
auto cnt = authors.erase("Barth, John");



11.3.4 map的下标操作



map<int, int> m;
m[0] = 1;   //添加对组元素


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


如果不需要计数最好用find



11.3.6 一个单词转换的map


//单词转换
void word_transform(ifstream& map_file, ifstream& input){
    auto trans_map = buildMap(map_file);  //保存转换规则
    string text;                          //保存输入中的每一行
    while(getline(input, text)){          //读取一行输入 
        istringstream stream(text);       //读取每个单词
        string word;
        bool firstword = true;            //控制是否打印空格
        while(stream >> word){
            //该if else控制打印空格
            if(firstword){
                firstword = false;
            }
            else{
                cout << " ";   //单词间打印空格
            }
            //transform返回它的第一个参数或其转换之后的形式
            cout << transform(word, trans_map);  //打印输出单词
        }
        cout << endl;   //输出完一行
    }
}
//建立转换映射
map<string, string> buildMap(ifstream& map_file){
    map<string, string> trans_map;  //保存转换规则
    string key;
    string value;
    //读取的第一个单词存入key中,行中剩余内容存入value中
    while(map_file >> key && getline(map_file, value)){
        if(value.size() > 1){
            trans_map[key] = value.substr(1);
        }
        else{
            throw runtime_error("no rule for" + key);
        }
    }
    return trans_map;
}
//生成转换文本
const string& transform(const string& s, const map<string, string>& m){
    auto map_it = m.find(s);
    if(map_it != m.cend()){
        return map_it->second;   //找到则使用替换短语
    }
    else{
        return s;   //原string
    }
}


11.4 无序容器


  • unordered_map


  • unordered_set


相关文章
|
21天前
|
设计模式 存储 Android开发
c++的学习之路:18、容器适配器与反向迭代器
c++的学习之路:18、容器适配器与反向迭代器
21 0
|
2月前
|
存储 算法 C语言
【C++ 迭代器实现 终篇】深入理解C++自定义容器和迭代器的实现与应用
【C++ 迭代器实现 终篇】深入理解C++自定义容器和迭代器的实现与应用
61 0
|
2月前
|
设计模式 程序员 C++
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
271 2
|
4天前
|
调度 C++ 容器
【C++】手搓 list 容器
本文我们实现了STL库中重要的list 的模拟实现,其中最重要莫过于迭代器的封装类的书写,这是前所未有的操作(对于我来说,我是第一次使用这种结构)。通过list 的模拟实现也帮我们巩固了类与对象的知识,也强化了指针操作的思路。欢迎大家讨论分析。
12 1
|
6天前
|
存储 设计模式 算法
【C++/STL】stack和queue(容器适配器、优先队列、双端队列)
【C++/STL】stack和queue(容器适配器、优先队列、双端队列)
13 1
|
13天前
|
存储 算法 C++
详解C++中的STL(标准模板库)容器
【4月更文挑战第30天】C++ STL容器包括序列容器(如`vector`、`list`、`deque`、`forward_list`、`array`和`string`)、关联容器(如`set`、`multiset`、`map`和`multimap`)和容器适配器(如`stack`、`queue`和`priority_queue`)。它们为动态数组、链表、栈、队列、集合和映射等数据结构提供了高效实现。选择合适的容器类型可优化性能,满足不同编程需求。
|
19天前
|
存储 算法 程序员
C++从入门到精通:2.2.1标准库与STL容器算法深度解析
C++从入门到精通:2.2.1标准库与STL容器算法深度解析
|
26天前
|
C++ 容器
约瑟夫经典问题C++,STL容器queue解法
约瑟夫经典问题C++,STL容器queue解法
14 0
|
1月前
|
容器
C++map/multimap容器
C++map/multimap容器
|
1月前
|
C++ 容器
C++入门到理解set/multiset容器、pair对组
C++入门到理解set/multiset容器、pair对组
C++入门到理解set/multiset容器、pair对组