C++primer练习11.9
练习11.9
定义一个map,将单词与一个行号的list关联,list中保存的是单词所出现的行号
void change(string&a) { if(isupper(a[0])) a[0]=tolower(a[0]); if(a[a.size()-1]==','||a[a.size()-1]=='.') a.erase(a.size()-1); } int main(int argc,char *argv[]) { map<string,list<int> > appeal; string line_temp,str_temp; unsigned line=0; ifstream in(argv[1]); if(!in) { cout<<"can't open the file"<<endl; exit(1);} while(getline(in,line_temp)) { ++line; istringstream instr(line_temp); while(instr>>str_temp) { change(str_temp); appeal[str_temp].push_back(line); } } }
练习11.10
可以定义一个vector<int>::iterator到int的map吗?list<int>::iterator到int的map呢?对于两种情况,如果不能,解释为什么
int main() { map<vector<int>::iterator,int> ma; map<list<int>::iterator,int> ma_li; return 0; }
练习11.11
不使用decltype重新定义bookstore
bool compareisbn(Sales_data&a,Sales_data&b) { return a.named()<b.named(); } int main(int argc,char *argv[]) { using F = bool(Sales_data &,Sales_data &); multiset<Sales_data,F*> bookstore(compareisbn); }
练习11.12
编写程序,读入string和int的序列,将每个string和int存入一个pair中,pair保存在一个vector中
int main(int argc,char *argv[]) { vector<pair<string,int>> inl; string word; int digit; while(cin>>word) { cin>>digit; inl.push_back(make_pair(word,digit)); } for(auto d:inl) cout<<d.first<<d.second<<endl; }
练习11.13
在上一题的程序中,至少有三种创建pair的办法。编写此程序的三个版本,分别采用不同的办法创建pair,解释你认为那种形式最易于理解
int main(int argc,char *argv[]) { vector<pair<string,int>> inl; string word; int digit; while(cin>>word) { cin>>digit; inl.push_back({word,digit}); } for(auto d:inl) cout<<d.first<<d.second<<endl; }
int main(int argc,char *argv[]) { vector<pair<string,int>> inl; string word; int digit; while(cin>>word) { cin>>digit; inl.push_back( pair<string,int>(word,digit)); } for(auto d:inl) cout<<d.first<<d.second<<endl; }
第一个make_pair和最后的显式构造都很清晰,个人喜欢用操作生成pair
练习11.14
扩展你在11.2.1节练习中编写的孩子的姓到名的map,添加一个pair的vector,保存孩子的名和生日
struct date{ unsigned month; unsigned day; date()=fault; date(unsigned a,unsigned b)::month(a),dau(b){} void print(){ cout << month << "-" << day << endl; } }; int main() { string fname; string name; int month,day; pair<string,Date> p; map<string,vector<pair<string,Date>>> family; while(cin >> fname >> name >> month >> day) { Date d(month,day); p = {name,d}; family[fname].push_back(p); } for(auto &member : family) { cout << "Member is:" << " " << endl; for(auto it = member.second.begin(); it != member.second.end();++it) cout << (*it).first << "." << member.first << " " << (*it).second.month << "-" << (*it).second.day << endl; cout << endl; } return 0; }
练习11.15
对一个int到vector<int>的map,其mapped_type、key_type和value_type分别是什么
::按顺序分别是vector<int>、int、pair<int,vector<int>
练习11.16
使用一个map迭代器编写一个表达式,将一个值赋给一个元素
int main() { map<int,int> digits{{1,2},{2,3}}; auto map_d=digits.begin(); map_d->second=11; cout<<map_d->second<<endl; }
练习11.17
假定c是一个string的multiset,v是一个string的vector,解释下面调用
copy(v.begin(),v.end(),inserter(c,c.end()));正确
copy(v.begin(),v.end(),back_inserter(c));错误 multiset没有push_back这个操作,尾插法不适合
copy(c.begin(),c.end(),inserter(v,v.end()));正确
copy(v.begin(),v.end(),back_inserter(v));正确
练习11.18
写出第382页循环中map_it的类型,不要使用auto
::map<string,string>::iterator map_set
练习11.19
定义一个变量,通过对11.2.2节中的名为bookstores的multiset调用begin()来初始化这个变量。写出变量类型
bool compareisbn(Sales_data&a,Sales_data&b) { return a.named()<b.named(); } int main() { using F = bool(Sales_data &,Sales_data &); multiset<Sales_data,F*> bookstore(compareisbn); set<Sales_data,F*>::const_iterator set_d=bookstore.begin(); }
练习11.20
重写11.1节练习的单词计数程序,使用insert代替下标操作,你认为哪个程序更容易编写和阅读
int main() { map<string,size_t> words; string word; while(cin>>word) { auto it=words.insert({word,1}); if(!it.second) { ++it.first->second; } } for(auto D:words) cout<<D.first<<D.second<<endl; }
下标或许更直接,只是因为如果忘记了insert的返回值就理解不了
练习11.21
假定word_count是一个string到size_t的map,word是一个string解释下面循环的作用
while(cin>>word)
++word_count.insert({word,0}).first->second;
::word第一次insert会给0+1,后面会不断给元素的second+1,起到了计数的作用
练习11.22
给定一个map<string,vector<int>>,对此容器的插入一个元素的insert版本,写出其参数类型和返回类型
::参数类型map<string,vector<int>>::value_type,返回类型pair<map<string,vector<int>>::iterator,bool>
练习11.23
用multimap重写以孩子的姓为关键字的map
int main() { multimap<string,size_t> resorst; string firstname; while(cin>>firstname) { string name; cin>>name; resorst.insert({firstname,{name}}); } }