笔记:C++学习之旅---关联容器

      关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的。与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。
      关联容器支持高效的关键字查找和访问。两个主要的关联容器类是mapset
map中的元素是一些关键字的-值(key-value)对:关键字起到索引的作用,值则表示与索引相关联的数据。set中每个元素只包含一个关键字:set支持高效的关键字查询操作--检查一个给定关键字是否在set中。

例子:
一个经典的使用关联数组的例子是单词计数程序:
#include
<iostream>
#include
<string>
#include
<map>
#include
<set>
using
namespace
std;

int
main()
{
            
map
<
string
,
size_t
> word_count;
            
string
word;
            
set
<
string
> exclude = {
"The"
,
"But"
,
"And"
,
"Or"
,
"An"
,
"A"
,
"the"
,
"but"
,
"and"
,
"or"
,
"an"
,
"a"
};
//忽略的单词
            cout <<
"请输入一串英文单词\n"
;
            
while
(cin >> word)
            {
                        
if
(word ==
"#"
)
                                    
break
;
                        
if
(exclude.find(word) == exclude.end())
                        {
                                    ++word_count[word];
                        }
            }
                        
for
(
const
auto
&w : word_count)
                        cout << w.first <<
" occurs "
<< w.second << ((w.second > 1) ?
" times "
:
" time "
) << endl;

            
return
0;
}
练习11.3 11.4:
编写你自己的单词计数程序,忽略大小写和标点。如,"example"“example,”和“Example”应该递增相同的计数器。

#include
<iostream>
#include
<map>
#include
<string>
#include
<algorithm>
using
namespace
std;

void
print(
map
<
string
,
size_t
> &
map
)
{
            
for
(
auto
&m : map)
                        cout <<m.first<<
":"
<<m.second<<endl;
}
void
word_count_pro(
map
<
string
,
size_t
> &
m
)
{
            
string
word;
            cout <<
"请输入一串英文单词\n"
;
            
while
(cin >> word)
            {
                        
if
(word ==
"#"
)
                                    
break
;
                        
for
(
auto
&ch : word)
                                    ch = towlower(ch);
//大小写转换;
                        word.erase(remove_if(word.begin(), word.end(), ispunct), word.end());
//ispunct 判断是否为标点符号或者特殊字符进行删除;
                        ++
m
[word];
            }
            print(
m
);
}
int
main()
{
            
map
<
string
,
size_t
> map;
            word_count_pro(map);
            
return
0;
}

关联容器的概述

#include
<iostream>
#include
<vector>
#include
<map>
#include
<set>
using
namespace
std;

int
main()
{
            
vector
<
int
> vec;
            
for
(
vector
<
int
>::
size_type
i = 0; i != 10; ++i)
            {
                        vec.push_back(i);
                        vec.push_back(i);
            }
            
set
<
int
> iset(vec.cbegin(), vec.cend());
            
multiset
<
int
> miset(vec.cbegin(), vec.cend());
            cout << vec.size() << endl;
//20
            cout << iset.size() << endl;
//10
            cout << miset.size() << endl;
//20
            
return
0;
}

练习11.7:
定义一个map,关键字是家庭的姓,值是一个vector,保存家中孩子(们)的名。编写代码,实现添加新的家庭以及向已有家庭中添加新的孩子。
#include
<iostream>
#include
<vector>
#include
<string>
#include
<map>
using
namespace
std;

void
print(
multimap
<
string
,
vector
<
string
>> &
family
)
{
            
//按照英文名称习惯打印名字,如Tom.Green
            
for
(
auto
&member : famil
y
)
            {
                        cout <<
"Mumber is:"
<<
" "
<< endl;
                        
for
(
auto
it = member.second.begin(); it != member.second.end(); ++it)
                        {
                                    cout << *it <<
"."
<< member.first << endl;
                        }
                        cout << endl;
            }
}
int
main()
{
            
string
fname =
""
, name =
""
;
            
vector
<
string
> vec = {
"Tom"
,
"Jerry"
,
"Lucy"
};
            
multimap
<
string
,
vector
<
string
>> family = { {
"Green"
, vec }, {
"white"
, vec } };

            print(family);
//打印结果

            
//先输入family name,然后自己name
            
//while (cin >> fname >> name)
            
//family[fname].push_back(name);

            
//修改地方,先输入名,再输入姓,可以重复保存了,所以不像上面那样来插入名字
            cout <<
"请输入你的名:\n"
;
            
while
(cin >> fname)
            {
                        
vector
<
string
> vec;
                        cout <<
"请输入你的性(输入end退出):\n"
;
                        
while
(cin >> name && name !=
"end"
)
//以end结束输入
                        {
                                    vec.push_back(name);
                        }
                                    family.insert({fname,vec });
//将姓插入到名前面
                                    
//添加新家庭后再次打印
                                    print(family);
            }
     
            
return
0;
}

pair类型
类似容器,pair是一个用来生成特定类型的模版。与其他标准库类型不同,pair的数据成员public的两个成员分别命名为first和second。

关联容器的操作

向map中添加元素
对于一个map进行insert操作时,必须记住元素类型是pair。

练习11.20:
重写单词计数程序,使用insert代替下标操作。你认为哪个程序更容易编写和阅读
#include
<iostream>
#include
<vector>
#include
<map>
#include
<string>
using
namespace
std;

int
main()
{
            
map
<
string
,
size_t
> word_count;
            
string
word;
            cout <<
"请输入一串字符串\n"
;
            
while
(cin >> word)
            {
                        
if
(word ==
"#"
)
                                    
break
;
                        
auto
ret = word_count.insert({ word, 1 });//创建一个pair
                        
if
(!ret.second)
                        {
                                    ++ret.first->second;//map中值部分
                        }
            }
            
for
(
auto
&w : word_count)
                        cout << w.first <<
" "
<< w.second << ((w.second > 1) ?
" times "
:
" time "
)<<endl;

            
return
0;
}

删除元素

练习11.31:
编写程序,定义一个作者及其作品的multimap。使用find在multimap中查找一个元素并用erase删除它。确保你的程序在元素不在map中时也能正常运行。
#include
<iostream>
#include
<string>
#include
<map>
#include
<algorithm>
using
namespace
std;

int
main()
{
            
multimap
<
string
,
string
> authors{ {
"alan"
,
"DMA"
}, {
"pezy"
,
"LeetCode"
}, {
"alan"
,
"CLRS"
},
            {
"wang"
,
"FTP"
}, {
"pezy"
,
"CP5"
}, {
"wang"
,
"CPP-Concurrency"
} };
            
            cout <<
"erase before:\n"
;
            
for
(
auto
&a : authors)
                        cout << a.first <<
":"
<<a.second<< endl;

            
string
author =
"pezy"
;
            
string
work =
"CP5"
;

            
auto
found = authors.find(author);
//找到作者;
            
auto
count = authors.count(author);
//记录次数;
            
while
(count)
            {
                        
if
(found->second == work)
//找到CP5,然后删除;
                        {
                                    authors.erase(found);
                                    
break
;
                        }
                        ++found;
                        --count;
            }
            cout <<
"erase after:\n"
;
            
for
(
const
auto
& author : authors)
                        cout << author.first <<
":"
<< author.second << std::endl;

            
return
0;
}

笔记:C++学习之旅---关联容器的更多相关文章

  1. 【c++ Prime 学习笔记】第11章 关联容器

    关联容器的元素按照关键字来保存和访问,而顺序容器的元素是按照在容器中的位置来保存和访问 关联容器支持高效的关键字查找和访问 2种关联容器: map中的元素是关键字-值对(key-value对),关键字 ...

  2. C++ Primer 读书笔记:第10章 关联容器

    第10章 关联容器 引: map set multimap multiset 1.pair类型 pair<string, int> anon anon.first, anon.second ...

  3. 笔记-JavaWeb学习之旅19

    Redis:redis是一款高性能的NOSQL系列的非关系型数据库 NOSQL: Not Only SQL ,意即"不仅仅是SQL",是一项全新的数据库理念,泛指非关系型数据库 r ...

  4. 笔记-JavaWeb学习之旅14

    JSTL:JavaServer Pages Tag Library JSP标准标签库 if标签 <%@ page import="java.util.ArrayList" % ...

  5. 笔记-JavaWeb学习之旅11

    请求转发:一种在服务器内部的资源跳转方式 使用步骤 1.通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path) ...

  6. 笔记-JavaWeb学习之旅8

    Window对象-定时器方法 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  7. 笔记-JavaWeb学习之旅7

    JavaScript基础 概念:一门客户端脚本语言,运行在客户端浏览器中,每一个浏览器都有JavaScript的解析引擎,是一个脚本语言,不需要编译,直接就可以被浏览器解析执行. JavaScript ...

  8. 笔记-JavaWeb学习之旅5

    CP30的演示 package cn.itcast.datasourcejdbc; import com.mchange.v2.c3p0.ComboPooledDataSource; import j ...

  9. 笔记-JavaWeb学习之旅3

    数据库的设计 1.多表之间的关系 一对一 一对一关系实现,可以在任意一方添加唯一外键指向另一方的主键 一对多 在多的一方建立外键指向一的一方建立主键 多对多 多对多关系实现需要借助第三张中间表.中间表 ...

  10. 笔记-JavaWeb学习之旅2

    数据库的基本概念 1.数据库:DataBase 简称 DB,用于存储和管理数据的仓库 特点: 1.持久化存储数据的,其实数据库就是一个文件系统, 2.方便存储和管理数据 3.使用了统一操作数据库 -- ...

随机推荐

  1. 查看app包名

    操作步骤: 1.cmd中输入命令:adb shell am monitor 2.启动需要获取包名的应用

  2. [C#]索引指示器

    参考代码: using System; namespace IndexerDemo { class StuInfo { public string Name; public string[] CouN ...

  3. FLINK集群搭建

    常用命令总结 启动/停止 flink 集群 ./bin/start-cluster.sh./bin/stop-cluster.sh 启动或停止JOBMANAGER bin/jobmanager.sh ...

  4. openssl 全面支持国密SM2/SM3/SM4加密算法

    sm4展示 代码 /** 文件名: https://github.com/liuqun/openssl-sm4-demo/blob/cmake/src/main.c */ #include <s ...

  5. word多级标题自动编号设置

    1.选择段落 ->多级列表 ->定义新的多级列表 2.级别设置 ,这里操作比较繁琐,要多注意[输入编号的格式]要通过[包含的级别编号来自]这一项目来设定 标题1: 标题2 标题3: 标题4 ...

  6. Python第六章实验报告

    一.实验内容:<零基础学Python>第六章实例和实战,以及一道作业题 二.实验环境:IDLE Shell 3.9.7 三.实验目的和要求:掌握定义和调用函数.变量的作用域.匿名函数.参数 ...

  7. python之tk学习,闲鱼搜索-小记

    (如想转载,请联系博主或贴上本博地址) 编程,逻辑,总是让人如痴如醉. 下面进入正题. 火热的天气配上火热的python,python的入门友好性让门外汉们都看到了希望.当然自己写的程序如果没有GUI ...

  8. 【picoCTF]cookies write up

    顾名思义,这一挑战涉及对cookie的简单操作.登录页面会显示一个搜索框,其中包含一个输入字段,用于检查您为其提供的 Cookie 类型. 点击链接,页面如下: 随便在框里输入内容,显示如下: 输出返 ...

  9. 第七章ssh sftp scp

    第七章ssh sftp scp 对数据进行了加密和压缩 版本号协商,可能客户端和服务端的版本号不一致,服务端向客户端发送一个ssh协商,告诉客户端使用的ssh协议的版本号是多少,客户端在接收到了这个协 ...

  10. JavaWeb学习笔记第二弹

    (续集)DQL:查询操作 1.排序查询 排序方式:(仅有一个排序参照时) 1.升序:ASC(默认) 命令:**select * from 表名 order by 列名 (asc);** 2.降序:DE ...