练习11.1:考察map和set的区别
map中的元素是 关键字-值 对,关键字起到索引作用,值则表示与索引相关联的数据
set中的元素只包含一个关键字,set支持搞笑的关键字查询
练习11.2:考察不同容器的使用场景
list:满足可以在任意的位置进行插入或者删除操作
vector:满足随机访问,但是插入和删除操作只在尾部进行
deque:满足随机访问,但是插入和删除操作只在头部或者尾部进行
map:存储字典型的数据
set:坏值检测
练习11.3:考察map的使用
1 #include<iostream> 2 #include<map> 3 #include<string> 4 using namespace std; 5 6 int main() 7 { 8 map<string,int>word_count; 9 string word; 10 while ( cin>>word ) ++word_count[word]; 11 for ( const auto& elem:word_count ) cout<<elem.first<<"="<<elem.second<<endl; 12 }
练习11.4:考察string的相关操作
1 #include<iostream> 2 #include<map> 3 #include<string> 4 #include<cctype> 5 #include<algorithm> 6 using namespace std; 7 8 int main() 9 { 10 map<string,int>word_count; 11 string word; 12 while ( cin>>word ) 13 { 14 string::iterator it=word.begin(); 15 while ( it!=word.end() ) 16 { 17 if ( ispunct(*it) ) it=word.erase(it); 18 else 19 { 20 *it=tolower(*it); 21 ++it; 22 } 23 } 24 ++word_count[word]; 25 } 26 for ( const auto& elem:word_count ) cout<<elem.first<<"="<<elem.second<<endl; 27 }
练习11.5:考察map和set的区别
set:元素的类型是关键字类型
map:元素的类型是 关键字-值对
根据元素的类型选择需要的容器
练习11.6:考察set和list的区别
set容器中的元素,值是不同的,顺序是有序的
list不是这样,容器的值和顺序取决于添加进容器中的元素的值和顺序
练习11.7:考察map的应用
1 #include<iostream> 2 #include<string> 3 #include<map> 4 #include<vector> 5 using namespace std; 6 7 int main() 8 { 9 map<string,vector<string> >family; 10 string lastName,firstName; 11 while ( cin>>lastName ) 12 { 13 while ( cin>>firstName && firstName!="end" ) 14 { 15 family[lastName].push_back(firstName); 16 } 17 } 18 for ( auto e:family ) 19 { 20 cout<<e.first<<":"<<endl; 21 for ( auto c:e.second ) 22 { 23 cout<<c<<" "; 24 } 25 cout<<endl; 26 } 27 }
练习11.8:考察set相较于vector的优势
1 #include<iostream> 2 #include<vector> 3 #include<string> 4 #include<algorithm> 5 using namespace std; 6 7 int main() 8 { 9 vector<string>vec; 10 string word; 11 while ( cin>>word ) 12 { 13 if ( find(vec.begin(),vec.end(),word)!=vec.end() ) vec.push_back(word); 14 } 15 }
(a)set中的元素是有序、不重复的
(b)set插入和删除任意元素的效率高
(c)set查找容器中的元素效率更高
练习11.9、11.10:考察map的定义
1 #include<iostream> 2 #include<map> 3 #include<string> 4 #include<list> 5 #include<algorithm> 6 using namespace std; 7 8 int main() 9 { 10 //练习11.9 11 map<string,list<int> >m; 12 13 //练习11.10 14 map<vector<int>::iterator,int>mv; 15 map<list<int>::iterator,int>ml; 16 17 vector<int>vi; 18 mv[vi.begin()]=0; 19 20 list<int>li; 21 ml[li.begin()]=0; 22 }
map<vector<int>iterator,int>是可以的
map<list<int>iterator,int>是不行的,因为list迭代器的操作<是没有定义的
练习11.12、11.13:考察pair的使用
1 #include<vector> 2 #include<string> 3 #include<iostream> 4 #include<utility> 5 using namespace std; 6 7 int main() 8 { 9 vector<pair<string,int> >vp; 10 string str; 11 int i; 12 while ( cin>>str>>i ) 13 { 14 vp.push_back(pair<string,int>(str,i)); 15 vp.push_back(make_pair(str,i)); 16 vp.push_back({str,i}); 17 vp.emplace_back(str,i); //与push_back()相比,避免了类的移动和拷贝更高效 18 } 19 for ( const auto& p:vp ) cout<<p.first<<":"<<p.second<<endl; 20 }
练习11.14:考察pair同其他容器的结合使用
1 #include<iostream> 2 #include<string> 3 #include<map> 4 #include<vector> 5 using namespace std; 6 7 int main() 8 { 9 map<string,vector<pair<string,string> > >family; 10 string lastName,firstName,birthday; 11 while ( cin>>lastName ) 12 { 13 while ( cin>>firstName && firstName!="end" ) 14 { 15 cin>>birthday; 16 family[lastName].emplace_back(firstName,birthday); 17 } 18 } 19 for ( auto e:family ) 20 { 21 cout<<e.first<<" "<<endl; 22 for ( auto c:e.second ) 23 { 24 cout<<c.first<<":"<<c.second<<endl; 25 } 26 cout<<endl; 27 } 28 }
练习11.15:考察关联容器额外的类型别名
1 #include<iostream> 2 #include<map> 3 #include<vector> 4 using namespace std; 5 6 int main() 7 { 8 map<int,vector<int> >mp; 9 map<int,vector<int> >::value_type v1; //v1是一个pair<const int,vector<int> > 10 map<int,vector<int> >::key_type v2; //v2是一个int 11 map<int,vector<int> >::mapped_type v3; //v3是一个vector<int> 12 }
练习11.16:考察map迭代器的使用
1 #include<iostream> 2 #include<map> 3 #include<vector> 4 #include<string> 5 using namespace std; 6 7 int main() 8 { 9 map<int,string>mp; 10 mp[25]="Yan"; 11 map<int,string>::iterator it=mp.begin(); 12 it->second="Chen"; 13 }
练习11.17:考察插入迭代器在set中的使用
只有第二个是不合法的,因为在multiset中没有push_back这个操作
其他操作均合法
练习11.18:考察map的迭代器
map_it的类型为map<string,size_t>::const_iterator