C++ Primer 第十一章答案

关联容器map,set 
习题11.1
map是键-值对应,其可储存两个类型,而vector单单是一个类型的储存容器。
map通过关键字获得值,而vector 通过迭代器或者下标引索获得。

习题11.2
list:频繁需要插入、删除操作
vector:需求更多的随机访问操作
deque:在两端插入删除、但又都对随机访问有需要
map:需要键值对应(字典),需要键值转换(如客户端输入字符串,转化为对类型一致对应对象的操作)
set:需求查询。

习题11.3
#include <iostream>
#include <string>
#include <vector>
#include <map>

using namespace std;
int main()
{
    map<string, size_t> word_count;
    string word;
    while (cin >> word)
    {
        word_count[word]++;
    }
    for (const auto& w : word_count)
        cout << w.first << " occurs " << w.second <<
        ((w.second > 1) ? " times " : " time ") << endl;
    system("pause");
    return 0;
}

习题11.4
#include <iostream>
#include <string>
#include <vector>
#include <map>

using namespace std;
int main()
{
    map<string, size_t> word_count;
    string word;
    while (cin >> word)
    {
        for (auto &w : word)
            w = tolower(w);
        word_count[word]++;
    }
    for (const auto& w : word_count)
        cout << w.first << " occurs " << w.second <<
        ((w.second > 1) ? " times " : " time ") << endl;
    system("pause");
    return 0;
}

习题11.5 
map是键值对应,而set只包括关键字

习题11.6
set不存在重复元素,而list存在。

习题11.7
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;


int main()
{
    map<string, vector<string>> word_count;
    string familyName,chidName;
    while (cout << "Please enter familyName " << endl, ( (cin >> familyName) && familyName != "NULL"))
    {
        cout << "Please enter childName" << endl;
        while (cin >> chidName && chidName != "NULL")
        {
            word_count[familyName].push_back(chidName);
        }
    }
    for (const auto& w : word_count)
    {
        cout << w.first << " " << endl;
        for (const auto& s : w.second)
            cout << s << " " << endl;
        cout << endl;
    }
    system("pause");
    return 0;
}

习题11.8
vector在添加每个元素时,使用find判断是否已有。set可以不会新加入已有的关键值。

习题11.9
map<string,list<int>>

习题11.10
可以定义,但是使用时,<是未定义的。

习题11.11

习题11.12 11.13
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <list>

using namespace std;


int main()
{
    std::vector<std::pair<std::string, int>> vec;
    std::string str;
    int i;
    while (std::cin >> str >> i)
        vec.push_back(std::pair<std::string, int>(str, i));
    // vec.push_back(std::make_pair(str, i));
    // vec.push_back({str, i});
    // vec.emplace_back(str, i); //!!! easiest way.
    for (const auto& p : vec)
        std::cout << p.first << ":" << p.second << std::endl;

    system("pause");
    return 0;
}
至于为什么emplace_back最简单也最有效,可参考
https://blog.csdn.net/sigh667/article/details/76540156
它是直接在容器管理的内存空间内构造函数

练习11.14
略。将名和生日定义为string。放入pair<string,string>。最终是map<string,pair<string,string>>

练习11.15
mapped_type:vector<int>,key_type:int ,value_type:pair<int, vector<int>>

练习11.16
std::map<int, std::string> map;
map[25] = "A";
std::map<int, std::string>::iterator it = map.begin();
it->second = "B";

练习11.17
第二个非法, multiset没有push_back

练习11.18
是没有找到word_count到底是个啥。。。。

练习11.19

练习11.20
#include <iostream>
#include <string>
#include <vector>
#include <map>

using namespace std;
int main()
{
    map<string, size_t> word_count;
    string word;
    while (cin >> word)
    {
        auto ret = word_count.insert({word,0});
                                if(!ret.frist) ++ret.frist.second;
    }
    for (const auto& w : word_count)
        cout << w.first << " occurs " << w.second <<
        ((w.second > 1) ? " times " : " time ") << endl;
    system("pause");
    return 0;
}

练习11.21
操作类似
auto ret = word_count.insert({word,0});
++ret.frist.second;

练习11.22
元素
std::pair<std::string, std::vector<int>>  
返回类型 std::pair<std::string, std::vector<int>>  

练习11.23
略。将下标操作,改为insert即可,在第一层循环auto ret = word_count.insert({word,0});
在第二层循环ret.frist.second.push_back()。

练习11.24
添加关键字为0的值为1 的pair

练习11.25
非法,v[0]不存在

练习11.26
(1)关键字,key_type
(2)值,mapped_type

练习11.27 
对关键字计数使用count,find查找关键字第一次出现的位置

练习11.28
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <list>
#include <set>
using namespace std;


int main()
{    
    map<string, vector<int>> m = { { "A",{ 1,2,3, } },{ "B",{ 2,3,4, } } };
    auto s1 = m.find("A");
    auto s2 = m.lower_bound("C");
    auto s3 = m.upper_bound("C");
    auto s4 = m.equal_range("C");

    system("pause");
    return 0;
}

练习11.29
upper_bound、lower_bound返回指向可以插入元素的迭代器
equal_range返回pair,其中的两个迭代器都是指向可以插入元素的迭代器

练习11.30
返回第一个匹配到的pair的frist元素

练习11.31
略,
注意点:全部删完,进入while(1),当find返回end的时候break,保证每一个都能找到

练习11.32

字典序的话稍微麻烦,map改为map<string,vector<string>>
将key_type,放入一个vector,使用sort进行排序。
然后依次放入新的map中,添加mapped_type时,使用find找到该作者所在pair的迭代器,后使用second即可。
最后输出。

练习11.33
#include <map>
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>

using std::string;
using std::ifstream;

std::map<string, string> buildMap(ifstream& map_file)
{
    std::map<string, string> trans_map;
    for (string key, value; map_file >> key && getline(map_file, value);)
        if (value.size() > 1)
            trans_map[key] =
            value.substr(1).substr(0, value.find_last_not_of(' '));
    return trans_map;
}

const string& transform(const string& s, const std::map<string, string>& m)
{
    auto map_it = m.find(s);
    return map_it == m.cend() ? s : map_it->second;
}

void word_transform(ifstream& map, ifstream& input)
{
    auto trans_map = buildMap(map);
    for (string text; getline(input, text);) {
        std::istringstream iss(text);
        for (string word; iss >> word;)
            std::cout << transform(word, trans_map) << " ";
        std::cout << std::endl;
    }
}

int main()
{
    ifstream ifs_map("../data/word_transformation_bad.txt"),
        ifs_content("../data/given_to_transform.txt");
    if (ifs_map && ifs_content)
        word_transform(ifs_map, ifs_content);
    else
        std::cerr << "can't find the documents." << std::endl;
}

练习11.34
没有该关键字,会直接创建

练习11.35
会直接插入,出现重复关键字
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值