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

2023-06-20,,

笔记: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++学习之旅---关联容器的相关教程结束。

《笔记:C++学习之旅---关联容器.doc》

下载本文的Word格式文档,以方便收藏与打印。