C++ primer 二十 map、sset关联容器

来源:互联网 发布:今日头条乱下软件 编辑:程序博客网 时间:2024/06/16 13:51
map简介

        map是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。对于迭代器来说,可以修改实值,而不能修改key。

map的功能

       自动建立Key - value的对应。key 和 value可以是任意你需要的类型。 根据key值快速查找记录,查找的复杂度基本是Log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次。 

快速插入Key - Value 记录。 

快速删除记录 

根据Key 修改value记录。 

遍历所有记录。 

        如前所示,当定义一个map时,必须既指明关键字类型和指明值类型;而定义一个 set时,只需指明关键字类型,因为set中没有值。毎个关联容器都定义了一个默认构造函数,它创建一个指定类型的空容器。我们也可以将关联容器初始化为另一个同类型容 器的拷贝,或是从一个值范围来初始化关联容器,只要这邱值可以转化为容器所需类型就 可以。在新标准F,我们也II了以对关联容器进行值初始化:

map<string, size_t> word_count; // 空容器

//列表初始化

set<string> exclude = {"the", "but", "and", "or", "an", "a",

"The", "But", "And", "Or", "An", "A"};

//三个元素;authors将姓映射为名

map<string, string>authors = { {’’Joyce", ’’James"},

{"Austen", "Jane"},

{"Dickens", "Charles"} };

        与以往一样,初始化器必须能转换为容器中元素的类型。对r set,元素类型就是关键字类型。

当初始化一个map时,必须提供关键字类型和值类型。我们将每个关键字-值对包围 在花拈号中:

{key, value}

来指出它们一起构成了 map中的一个元素。在每个花括号中,关键字是第一个元素,值是第二个。因此,authors将姓映射到名,初始化后它包含三个元素。

初始化 multimap 或 multiset

        一个map或set中的关键字必须是唯一的,即,对于一个给定的关键字,只能有一 个元素的关键字等于它。容器multimap和multiset没有此限制,它们都允许多个元素具有相同的关键字。

       下面的例子展示了具有唯一关键字的容器与允许重复关键字的容器之间的区别。首先,我们将创建一个名为ivec的保存int的vector,它包含20个元素:0到9每个整数有两个拷贝。我们将使用此vector初始化一个set和一个multiset:

//使用vector初始化set和multiset 

void multiset1()

{

vector<int>ivec;

//定义一个有20个元素的vector,保存0到9每个整数的两个拷贝

for(vector<int>::size_type i=0;i!=10;i++)

{//每个数重复保存一次

ivec.push_back(i);

ivec.push_back(i);

}

//// iset包含来自ivec的不重复的元素;miset包含所有20个元素 set<int>

set<int>iset(ivec.cbegin(),ivec.cend());

multiset<int>miset(ivec.cbegin(),ivec.cend());

cout<<"vector is num:"<<ivec.size()<<endl;//打印出 20

cout<<"set is num:"<<iset.size()<<endl;//打印出 10

cout<<"multiset is num:"<<miset.size()<<endl;//打印出 20

}

        即使我们用整个ivec容器米初始化iset,它也只含有10个元素:对应ivec中每个不同的元素。另一方面,miset有20个元素,与ivec中的元素数量一样多。

下面再举一个列子:定义一个map,关键字是家庭的姓,值是一个vector,保存家中孩子(们) 的名。实现添加新的家庭以及向已有家庭中添加新的孩子。

//map<string,vector<string>>姓和孩子名

void map_home()

{

map<string,vector<string>> mvhome;//定义map 

string fname; //姓 

string lname;//孩子的名 

cout<<"input the first name:";

while(cin>>fname)

{

cout<<"input the child name:";

cin>>lname;

//添加姓和名 ,名是vector<string>类型需要 push_back压入 

mvhome[fname].push_back(lname);

cout<<"input the first name:";

}

for(const auto &w:mvhome) //输出 

{   //输出 姓 

    cout<<"father is:"<<w.first<<"\nchild is:";

    for(auto &l:w.second)//输出 孩子的名字 

        cout<<l<<" ";

    cout<<endl<<endl;

}

cin.clear();

}

源文件:

#include<iostream>
#include<map>
#include<set>
#include<vector>
#include<string>
using namespace std;
void multiset1();//使用vector初始化set和multiset 
void map_home();//map<string,vector<string>>姓和孩子名 
int main()
{
//use the map
map<string,size_t>word_count;//string到size_t的空map
string word;
cout<<"input words:\n";
while(cin>>word)//提取word的计数器并将其加1 
++word_count[word];//对map中的每个元素 
for(const auto &w:word_count)
cout<<w.first<<" ocurs "<<w.second<<((w.second>1)?" times":" time")<<endl;
       cout<<endl;
       cout<<endl;
       cin.clear();
//use the set    
set<string> exclude={"The","But","And","Or","An","A",
         "the","but","and","or","an","a"};
map<string,size_t>words;//string到size_t的空map
cout<<"input words:\n";
while(cin>>word)//提取word的计数器并将其加1 
    if(exclude.find(word)==exclude.end())
++words[word];//对map中的每个元素 
for(const auto &w:words)
cout<<w.first<<" ocurs "<<w.second<<((w.second>1)?" times":" time")<<endl;
        cin.clear();
       //multiset可重复的关联容器 
multiset1();
map_home();// 
return 0;
}
//使用vector初始化set和multiset 
void multiset1()
{
vector<int>ivec;
//定义一个有20个元素的vector,保存0到9每个整数的两个拷贝
for(vector<int>::size_type i=0;i!=10;i++)
{//每个数重复保存一次
ivec.push_back(i);
ivec.push_back(i);
}

//// iset包含来自ivec的不重复的元素;miset包含所有20个元素 set<int>
set<int>iset(ivec.cbegin(),ivec.cend());
multiset<int>miset(ivec.cbegin(),ivec.cend());
cout<<"vector is num:"<<ivec.size()<<endl;//打印出 20
cout<<"set is num:"<<iset.size()<<endl;//打印出 10
cout<<"multiset is num:"<<miset.size()<<endl;//打印出 20

}
//map<string,vector<string>>姓和孩子名
void map_home()
{
map<string,vector<string>> mvhome;//定义map 
string fname; //姓 
string lname;//孩子的名 
cout<<"input the first name:";
while(cin>>fname)
{
cout<<"input the child name:";
cin>>lname;
//添加姓和名 ,名是vector<string>类型需要 push_back压入 
mvhome[fname].push_back(lname);

cout<<"input the first name:";
}
for(const auto &w:mvhome) //输出 
{   //输出 姓 
    cout<<"father is:"<<w.first<<"\nchild is:";
    for(auto &l:w.second)//输出 孩子的名字 
        cout<<l<<" ";
    cout<<endl<<endl;
}
cin.clear();
}

运行结果:



0 0
原创粉丝点击