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}});
    }
   
 } 

 

posted @ 2022-07-28 21:33  yddl  阅读(33)  评论(0编辑  收藏  举报