栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

《C++ Primer》第11章 11.4节习题答案

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

《C++ Primer》第11章 11.4节习题答案

《C++ Primer》第11章 关联容器

11.4节 无序容器 习题答案

练习11.37:一个无序容器与其有序版本相比有何优势?有序版本有何优势?

【出题思路】

理解无序关联容器与有序版本的差异。

【解答】

无序版本通常性能更好,使用也更为简单。有序版本的优势是维护了关键字的序。当元素的关键字类型没有明显的序关系,或是维护元素的序代价非常高时,无序容器非常有用。但当应用要求必须维护元素的序时,有序版本就是唯一的选择。

练习11.38:用unordered_map重写单词计数程序(参见11.1节,第375页)和单词转换程序(参见11.3.6节,第391页)。

【出题思路】

本题练习使用无序关联容器。

【解答】

对单词计数程序仅有的两处修改是将包含的头文件map改为unordered_map,以及将word_count的类型由map改为unordered_map。尝试编译、运行此程序,你会发现,由于无序容器不维护元素的序,程序的输出结果与第3题的输出结果的顺序是不同的。

#include 
#include 
#include 
#include 
#include 

using std::cout;
using std::endl;
using std::ifstream;
using std::unordered_map;
using std::string;
//using namespace std;


int main(int argc, const char * argv[])
{
    ifstream in(argv[1]);
    if(!in)
    {
        cout << "打开输入文件失败!" << endl;
        exit(1);
    }

    unordered_map word_count;   //string到count的映射
    string word;
    while(in >> word)
        ++word_count[word];//这个单词的出现次数加1

    for(const auto &w: word_count)//对map中的每个元素
    {
        //打印结果
        cout << w.first << "出出了 " << w.second << " 次" << endl;
    }
    return 0;
}

data11_38.txt文件内容如下:

the quick red fox jumps over the the slow over red turtle

设置命令行参数:

 运行结果:

 单词转换程序的修改类似。由于程序中不再有元素内容的顺序输出,因此输出结果与有序版本没有什么不同。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

unordered_map buildMap(ifstream &map_file)
{
    unordered_map trans_map;//保存转换规则
    string key;//要转换的单词
    string value;//用来替换的内容
    //读取第一个单词存入key,这一行的剩余内容存入value
    while(map_file >> key && getline(map_file, value))
    {
        if(value.size() > 1)//检查是否确实存在转换规则
            trans_map[key] = value.substr(1);//跳过前导空白
        else
            throw runtime_error("no rule for " + key);
    }

    return trans_map;
}

const string &transform(const string &s, const unordered_map &m)
{
    //完成具本体转换工作,这个函数是程序的核心
    auto map_it = m.find(s);
    //如果这个单词在转换映射表中
    if(map_it != m.cend())
        return map_it->second;//用映射表指定内容替换单词
    else
        return s;//否则原样返回单词
}

//第一个参数为转换规则文件
//第二个参数是要转换的文本文件
void word_transform(ifstream &map_file, ifstream &input)
{
    auto trans_map = buildMap(map_file);//保存转换规则
    //调试用:映射表创建好后打印它
    cout << "Here is our transformation map:nn";
    for(auto entry: trans_map)
        cout << "key: " << entry.first << "tvalue: " << entry.second << endl;
    cout << "nn";
    //对给定文本进行转换
    string text;//保存从输入读取的每一行
    while(getline(input, text)) //从输入读取一行
    {
        istringstream stream(text);//读取每个单词
        string word;
        bool firstword = true;//控制是否打印空格
        while(stream >> word)
        {
            if(firstword)
                firstword = false;
            else
                cout << " ";//打单词间打印空格
            //转换结果可能是另一个字符串也可能是原单词
            cout << transform(word, trans_map);//打印结果
        }
        cout << endl;//当前行转换完毕,打印回车
    }
}

int main(int argc, const char * argv[])
{
    //打开两个文件并检查是否打开成功
    if(argc != 3)
        throw runtime_error("wrong number of arguments");

    ifstream map_file(argv[1]);//打开转换规则文件
    if(!map_file)//检查是否打开成功
        throw runtime_error("no transformation file");

    ifstream input(argv[2]);//打开转换的文件
    if(!input)//检查是否打开成功
        throw runtime_error("no input file");

    word_transform(map_file, input);

    return 0;//退出主函数时文件会自动关闭
}

data11_38_map.txt文件内容如下:

brb be right back
k okay?
y why
r are
u you
pic picture
the thanks!
l8r later

data11_38_input.txt文件内容如下:

where r u
y don’t u send me a pic
k the l8r

设置命令行参数:

 运行结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/300218.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号