纯原创 转载请注明出处:http://blog.youkuaiyun.com/axuan_k
11.1 11.2 11.4
#include<iostream>
#include<map>
#include<set>
using namespace std;
int main(){
// 11.1
// vector是一个顺序容器,该容器每个对象通过下标访问
// map是一个关联容器,它保存的是key-value对,map可以通过key快速查询对应的value
// 11.2
// list: 需要自己实现字符串的各种操作
// deque: 模拟各种队列
// map: 实现字典的快速查找
// set: 需要保存一个集合
// 11.4
map<string,int>mp;
string str,temp;
while(cin>>temp){
str="";
for(char i:temp)
if(i>='A'&&i<='Z')
str+=i+32;
else if(i>='a'&&i<='z')
str+=i;
mp[str]++;
}
for(const auto& i:mp)
cout<<i.first<<" "<<i.second<<endl;
return 0;
}
11.5 11.6 11.7 11.8
#include<iostream>
#include<map>
#include<set>
#include<vector>
#include<sstream>
using namespace std;
int main(){
// 11.5 11.6
// map中保存的key-value对,当我们需要通过一个值快速索引另一个值时,应该选择使用map
// set中只保存了key,不会包含重复的元素,同时内部元素是有序的,当我们需要统计集合时,应该选择set
// list既保存重复元素,同时内部是无序的,但list插入,删除内部元素更加效率.当我们需要频繁修改内容时应该选择使用list
// 11.7
map<string,vector<string>>mp;
string temp,first,last;
while(getline(cin,temp)){
istringstream istr(temp);
istr>>first;
istr>>last;
mp[last].push_back(first);
}
for(const auto& i:mp)
for(const auto& j:i.second)
cout<<j<<endl;
// 11.8
vector<string>vec;
int flag;
string str;
while(cin>>str){
flag=0;
for(const string& i:vec)
if(i==str){
flag=1;
break;
}
if(flag)
continue;
vec.push_back(str);
}
for(const string& i:vec)
cout<<i<<" ";
cout<<endl;
// 使用set可以不用每次插入str都要遍历整个容器
return 0;
}
11.9 11.10 11.11
#include<iostream>
#include<map>
#include<set>
#include<list>
#include<vector>
#include<sstream>
#include"Sales_data.h"
using namespace std;
bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
{
return lhs.isbn() < rhs.isbn();
}
int main(){
// 11.9
map<string,list<int>>mp;
string temp,str;
int num=0;
while(getline(cin,temp)){
++num;
istringstream istr(temp);
while(istr>>str)
mp[str].push_back(num);
}
for(auto i:mp){
for(auto j:i.second)
cout<<j<<" ";
cout<<endl;
}
// 11.10
map<vector<int>::iterator,int>mp1;
map<list<int>::iterator,int>mp2;
vector<int>vec;
mp1.insert({vec.begin(),0});
list<int>lst;
mp2.insert({lst.begin(),0}); // 编译出错 ,因为key值不满足严格弱序
// 10.11
using func=bool(const Sales_data&,const Sales_data&);
multiset<Sales_data,func*>bookstore(compareIsbn);
return 0;
}
11.12 11.13 11.14
#include<iostream>
#include<vector>
#include<sstream>
#include<map>
#include<string>
using namespace std;
int main()
{
// 11.12
vector<pair<string,int>>vec;
int v;
string str;
while(cin>>str>>v){
vec.push_back(make_pair(str,v));
}
for(const auto& i:vec)
cout<<i.first<<" "<<i.second<<endl;
// 11.13
vec.push_back(make_pair("a",1));
vec.push_back({"b",2});
vec.emplace_back("c",3);
// 第二种更易理解 第三种更简洁
// 11.14
map<string, vector< pair<string,string> > >mp;
string temp,first,last,birth;
while(getline(cin,temp)){
istringstream istr(temp);
istr>>first;
istr>>last;
istr>>birth;
mp[last].emplace_back(first,birth);
}
for(const auto& i:mp)
for(const auto& j:i.second)
cout<<j.first<<" "<<j.second<<endl;
return 0;
}
11.15 11.16 11.17 11.19
#include<iostream>
#include<vector>
#include<sstream>
#include<map>
#include<algorithm>
#include<string>
#include<set>
#include"Sales_data.h"
using namespace std;
int main()
{
// 11.15
map<int,vector<int>>::mapped_type v1; //vector<int>
map<int,vector<int>>::key_type v2; //int
map<int,vector<int>>::value_type v3; //pair<const int,vector<int>>
// 11.16
map<int,string>mp{{1,"s"}};
auto it=mp.begin();
it->second="s2";
for(auto i:mp)
cout<<i.first<<" "<<i.second<<endl;
// 11.17
vector<string>v;
using func=bool(const string&,const string&);
multiset<string,func*>c;
copy(v.begin(), v.end(), inserter(c, c.end())); // ok
copy(v.begin(), v.end(), back_inserter(c)); //不合法 map没有push_back操作
copy(c.begin(), c.end(), inserter(v, v.end())); // ok
copy(c.begin(), c.end(), back_inserter(v)); // ok
// 11.19
using compareType = bool (*)(const Sales_data&, const Sales_data& rhs);
multiset<Sales_data, compareType> bookstore(compareIsbn);
multiset<Sales_data, compareType>::iterator c_it = bookstore.begin();
return 0;
}
11.20 11.21 11.22 11.23
#include <iostream>
#include <map>
#include<vector>
#include <string>
#include<sstream>
using namespace std;
int main()
{
// 11.20
map<string, size_t> word_count;
string word;
while (cin >> word) {
auto ret = word_count.insert({word, 1});
if (!ret.second) ++ret.first->second;
// ++word_count[word];
// 下标版更简洁 不需要多余的判断
}
for (const auto& w : word_count)
cout << w.first << " " << w.second
<< ((w.second > 1) ? " times" : "time") << endl;
// 11.21
++word_count.insert({word,0}).first->second;
// word_count.insert({word,0})返回一个pair对象,pair中的第一个元素是一个指向 该map的迭代器,
// 这个迭代器指向的第二个元素即为key(word)映射的value(size_t类型)值. ++使这个值自增.
// 11.22
map<string,vector<int>>mp2;
pair<string, vector<int>> p={"str",{1,2,3}}; // 参数类型
pair<map<string, vector<int>>::iterator, bool> ret=mp2.insert(p); // 返回值类型
// 11.23
multimap<string,string>mp;
string temp,first,last;
while(getline(cin,temp)){
istringstream istr(temp);
istr>>first;
istr>>last;
mp.insert({last,first});
}
for(const auto& i:mp)
cout<<i.first<<" "<<i.second<<endl;
return 0;
}
11.24 11.25 11.26
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
// 11.24
map<int,int>m;
m[0]=1;
// 添加一个pair<key,value> {0,1} 加入map容器
//11.25
vector<int>v;
v[0]=1;
// 将顺序容器vector中的第一个位置的值更改为1
// 但这里的vector是空的,也就没有第一个值 会抛出异常
cout<<v[0]<<endl;
// 11.26
map<string,int>mp{{"123",1},{"234",2}};
int a=mp.at("123");
int b=mp["234"];
map<string,int>::mapped_type c=mp["123"];
//下标是该map的key_type类型 返回的是mapped_type类型
return 0;
}
11.27 11.28 11.29 11.30 11.31 11.32
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
// 11.27
// count 在mutimap 和 multiset中统计某个元素(key)出现的次数
// find 在其他关联容器中查询某个key
//11.28
vector<int>vec{1,2,3};
map<string,vector<int>>mp{{"str",vec}};
map<string,vector<int>>::iterator d=mp.find("str");
cout<<d->first<<endl;
//11.29
bool a,b,c;
a=mp.end()==(mp.upper_bound("zzzz"));
//返回 xx.end()
b=mp.end()==(mp.lower_bound("zzzz"));
//返回 xx.end()
auto pos=mp.equal_range("zzzz");
//返回 {xx.end(),xx.end()}的pair
if(pos.first==mp.end()&&pos.second==mp.end())
c=1;
cout<<a<<" "<<b<<" "<<c<<endl;
// 11.30
// cout << pos.first->second << endl;
// pos.first为equal_range()返回的迭代器pair中的第一个迭代器(range的起始位置)
// pos.first->second为起始位置迭代器的指向的第二个元素(size_t类型的元素)
// 11.31
multimap<string,string>mmp{{"john","ice"},{"john","fire"},{"martin","song"},{"martin","the song of ice and fire"}};
pair<string,string>p={"john","fire"}; //待删除的组合
auto it =mmp.find(p.first);
int num=mmp.count(p.first);
while(num--){
if(p.second==it->second){
mmp.erase(it);
break;
}
it++;
}
for(auto i:mmp)
cout<<i.first<<" "<<i.second<<endl;
// 11.32
multimap<string,string>mmp2{{"john","ice"},{"john","fire"},{"martin","song"},{"martin","the song of ice and fire"}};;
map<string,set<string>>mp2;
for(auto i:mmp2)
mp2[i.first].insert(i.second);
for(auto i:mp2){
cout<<i.first<<" ";
for(auto j:i.second)
cout<<j<<",";
cout<<endl;
}
return 0;
}
11.34 11.35 11.36
#include<iostream>
#include<string>
#include<vector>
#include<map>
using nsmespace std;
int main(){
// 11.34
// 会发生编译错误
// 因为函数提供的参数为const map
// 而下标能够修改map 所有不允许使用
// 11.35
// 如果重复出现多次同样的key值
// 用下标操作后面的value会替换前面的value,而insert则不会替换
// 11.36
// 仅包含一个key和一个空格 并不会有任何影响
// 函数中判断value.size()<=1 即后面没有value则抛出异常
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// 11.37
// 无序版本优势:当容器中key没有明显的顺序关系时更有用,且不需要耗费多余的时间来维护容器中的key序列
// 有序版本优势:当容器中key有明显的顺序关系时更有用,且我们不需要考虑排序问题,容器自动维护序列
return 0;
}