【足迹C++primer】38、关联容器操作(2)

关联容器操作(2)

map的下标操作

map的下标操作

map和unordered_map容器提供了下标运算符合一个对应的at函数

对于一个map使用下标操作,其行为与数组或vector上的下标操作很不相同:

使用一个不再容器中的关键字作为下标,会添加一个此关键字的元素到map中

map和unordered_map的下标操作

c[k] 返回关键字为k的元素,如果关键字k不再c中,添加一个关键字为k的元素,对其进行值初始化

c.at(k) 访问关键字为k的元素,带参数检测,如果k不再c重那么返回一个异常,out_of_range

与vector和string不同,map下标运算符返回的类型与解引用map迭代器得到的类型不同。

访问元素

如果我们关心的只不过是特定元素是否在容器中的时候,泛型算法find是最佳的选择

void fun1()
{
    set<int> iset={0,1,2,3,4,5,6,7,8,9};
    iset.find(1);   //返回一个迭代器,指向key==1的元素
    iset.find(11);  //返回一个迭代器,值指向iset.end()
    iset.count(1);  //返回1
    iset.count(11); //返回0
}

今天上传的有点晚了,放假了,人也懒了- -

对map使用find代替下标操作

下标操作会自动添加元素,不好

void fun2()
{
    map<string, size_t> word_count;
    string word;
    while(cin>>word)
        ++word_count[word];

    if(word_count.find("foobar") == word_count.end())
        cout<<"foobar is not in the map "<<endl;
}

在multimap和multiset中查找元素

当我们遍历multimap和multiset的时候,保证可以得到序列中所有具有给定关键字的元素

void fun3()
{
    multimap<string, string> authors;
    string search_item("Alain de Botton");  //要查找的作者
    auto entries=authors.count(search_item);    //元素的数量
    auto iter=authors.find(search_item);     //此作者的第一本书
    //用一个循环查找此作者的所有著作
    while(entries)
    {
        cout<<iter->second<<endl;   //打印书名
        ++iter;             //指向下一个
        --entries;          //记录打印了多少书
    }
}

一种不同的,面向迭代器的解决方法

lower_bound返回迭代器可能指向一个具有给定关键字的元素,但也可能不指向。

如果关键字不在容器中,则lower_bound会返回关键字的第一个安全插入点--不影响

容器中元素顺序的插入位置

void fun4()
{
    //authors和search_item的定义,和前面的程序一样
    //beg和end表示对应此作者的元素的范围
    multimap<string, string> authors;
    string search_item("Alain de Botton");  //要查找的作者

    for(auto beg=authors.lower_bound(search_item),
             end=authors.upper_bound(search_item) ; beg != end; ++beg)
        cout<<beg->second<<endl;    //打印每个题目

    //upper_bound调用将end指向最后一个匹配search_item的元素的后一位
}

有木有发现,我现在博客越来越顺畅啦,相信大家也看看出来了吧,嘿嘿,我每次都打好底稿,然后再上传,边传边改,这样就不会像以前那样了,很乱,而且有点赶时间的嫌疑,

equal_range函数

不用lower_bound和upper_bound直接调用equal_range即可。

这个函数接受一个关键字,返回一个迭代器pair,第一个迭代器指向

第一个和关键字匹配的元素,第二个指向和最后一个匹配的元素的后一个位置

void fun5()
{
    //authors和search_item的定义,和前面的程序一样
    //pos保存迭代器对,表示关键字匹配的元素范围
    multimap<string, string> authors;
    string search_item("Alain de Botton");  //要查找的作者

    pair<multimap<string, string>::iterator, multimap<string, string>::iterator> pos;
    for(pos=authors.equal_range(search_item); pos.first != pos.second ; ++pos.first)
        cout<<pos.first->second<<endl;  //打印每个题目

}

一个单词转换的map

施主,这次能看懂多少看个人造化了^_^。

单词转换文件,我把它叫做map_file.txt

brb be right back

k okay?

y why

r are

u you

pic picture

thk thanks!

18r later

我们希望转换的文本,这个叫做input.txt

where r u

y dont u send me a pic

k thk 18r

程序输出生成这样:

where are you

why dont you send me a picture

okay? thanks! later

#include<iostream>
#include<fstream>
#include<sstream>
#include<map>
#include<set>
#include<string>
#include<utility>       //pair

using namespace std;

map<string, string> bulidMap(ifstream &map_file)
{
    map<string, string> trans_map;  //保存转换规则
    string key;     //要转换的单词
    string value;   //替换后的内容
    //读取第一个单词存入key中,行中剩余内容存入value
    while(map_file>>key && getline(map_file, value))
    {
        if(value.size() > 1)    //坚持是否有转换规则
        {
            value=value.substr(1);     //跳过前导空格
            //插入map
            trans_map.insert({key, value});
        }
        else
            throw runtime_error(" no rule for "+key);
    }
    return trans_map;
}

const string & transform(const string &s, const map<string, string> &m)
{
    //实际转换工作;此部分是程序核心
    auto map_it=m.find(s);
    //如果单词在转换规则map中
    if(map_it != m.cend())
    {
        return map_it->second;      //使用替换短语
    }
    else
    {
        return s;       //返回原值
    }

}

void word_transform(ifstream &map_file, ifstream &input)
{
    auto trans_map=bulidMap(map_file);  //保存转换规则
    string text;        //保存输入中的没一行
    while(getline(input, text)) //读取输入一行
    {
        istringstream stream(text);     //读取每个单词
        string word;
        bool firstword=true;    //控制是否打印空格

        while(stream>>word)
        {
            if(firstword)
                firstword=false;
            else
                cout<<" ";      //在单词之间打印一个空格

            //transform返回它的第一个参数或其转换之后的形式
//            cout<<endl<<"-------------------------------------"<<endl;
//            cout<<"这个单词是:"<<word<<endl;
//            cout<<"-------------------------------------"<<endl;
            cout<<transform(word, trans_map);   //打印输出
        }
        cout<<endl;     //完成一行的转换
    }
}

int main()
{
    ifstream map_file,input;
    map_file.open("map_file.txt");
    input.open("input.txt");

    word_transform(map_file, input);

    map_file.close();
    input.close();

    return 0;
}

好的劳动了一上午的成果!!!

/**
* 功能:关联容器操作
* 时间:2014年6月27日09:55:55
* 作者:cutter_point
*/

#include<iostream>
#include<fstream>
#include<sstream>
#include<map>
#include<set>
#include<string>
#include<utility>       //pair

using namespace std;

//map的下标操作
//map和unordered_map容器提供了下标运算符合一个对应的at函数
//对于一个map使用下标操作,其行为与数组或vector上的下标操作很不相同:
//使用一个不再容器中的关键字作为下标,会添加一个此关键字的元素到map中

/*
map和unordered_map的下标操作
c[k] 返回关键字为k的元素,如果关键字k不再c中,添加一个关键字为k的元素,对其进行值初始化
c.at(k) 访问关键字为k的元素,带参数检测,如果k不再c重那么返回一个异常,out_of_range
*/

//与vector和string不同,map下标运算符返回的类型与解引用map迭代器得到的类型不同。

//访问元素
//如果我们关心的只不过是特定元素是否在容器中的时候,find是最佳的选择
void fun1()
{
    set<int> iset={0,1,2,3,4,5,6,7,8,9};
    iset.find(1);   //返回一个迭代器,指向key==1的元素
    iset.find(11);  //返回一个迭代器,值指向iset.end()
    iset.count(1);  //返回1
    iset.count(11); //返回0
}

//对map使用find代替下标操作
//下标操作会自动添加元素,不好
void fun2()
{
    map<string, size_t> word_count;
    string word;
    while(cin>>word)
        ++word_count[word];

    if(word_count.find("foobar") == word_count.end())
        cout<<"foobar is not in the map "<<endl;
}

//在multimap和multiset中查找元素
//当我们遍历multimap和multiset的时候,保证可以得到序列中所有具有给定关键字的元素
void fun3()
{
    multimap<string, string> authors;
    string search_item("Alain de Botton");  //要查找的作者
    auto entries=authors.count(search_item);    //元素的数量
    auto iter=authors.find(search_item);     //此作者的第一本书
    //用一个循环查找此作者的所有著作
    while(entries)
    {
        cout<<iter->second<<endl;   //打印书名
        ++iter;             //指向下一个
        --entries;          //记录打印了多少书
    }
}

//一种不同的,面向迭代器的解决方法
/*
lower_bound返回迭代器可能指向一个具有给定关键字的元素,但也可能不指向。
如果关键字不在容器中,则lower_bound会返回关键字的第一个安全插入点--不影响
容器中元素顺序的插入位置
*/
void fun4()
{
    //authors和search_item的定义,和前面的程序一样
    //beg和end表示对应此作者的元素的范围
    multimap<string, string> authors;
    string search_item("Alain de Botton");  //要查找的作者

    for(auto beg=authors.lower_bound(search_item),
             end=authors.upper_bound(search_item) ; beg != end; ++beg)
        cout<<beg->second<<endl;    //打印每个题目

    //upper_bound调用将end指向最后一个匹配search_item的元素的后一位
}

//equal_range函数
/*
不用lower_bound和upper_bound直接调用equal_range即可。
这个函数接受一个关键字,返回一个迭代器pair,第一个迭代器指向
第一个和关键字匹配的元素,第二个指向和最后一个匹配的元素的后一个位置
*/
void fun5()
{
    //authors和search_item的定义,和前面的程序一样
    //pos保存迭代器对,表示关键字匹配的元素范围
    multimap<string, string> authors;
    string search_item("Alain de Botton");  //要查找的作者

    pair<multimap<string, string>::iterator, multimap<string, string>::iterator> pos;
    for(pos=authors.equal_range(search_item); pos.first != pos.second ; ++pos.first)
        cout<<pos.first->second<<endl;  //打印每个题目

}

//一个单词转换的map
//施主,这次能看懂多少看个人造化了^_^。
/*
单词转换文件
brb be right back
k okay?
y why
r are
u you
pic picture
thk thanks!
18r later
我们希望转换的文本
where r u
y dont u send me a pic
k thk 18r
程序输出生成这样:
where are you
why dont you send me a picture
okay? thanks! later
*/
map<string, string> bulidMap(ifstream &map_file)
{
    map<string, string> trans_map;  //保存转换规则
    string key;     //要转换的单词
    string value;   //替换后的内容
    //读取第一个单词存入key中,行中剩余内容存入value
    while(map_file>>key && getline(map_file, value))
    {
        if(value.size() > 1)    //坚持是否有转换规则
        {
            value=value.substr(1);     //跳过前导空格
            //插入map
            trans_map.insert({key, value});
        }
        else
            throw runtime_error(" no rule for "+key);
    }
    return trans_map;
}

const string & transform(const string &s, const map<string, string> &m)
{
    //实际转换工作;此部分是程序核心
    auto map_it=m.find(s);
    //如果单词在转换规则map中
    if(map_it != m.cend())
    {
        return map_it->second;      //使用替换短语
    }
    else
    {
        return s;       //返回原值
    }

}

void word_transform(ifstream &map_file, ifstream &input)
{
    auto trans_map=bulidMap(map_file);  //保存转换规则
    string text;        //保存输入中的没一行
    while(getline(input, text)) //读取输入一行
    {
        istringstream stream(text);     //读取每个单词
        string word;
        bool firstword=true;    //控制是否打印空格

        while(stream>>word)
        {
            if(firstword)
                firstword=false;
            else
                cout<<" ";      //在单词之间打印一个空格

            //transform返回它的第一个参数或其转换之后的形式
//            cout<<endl<<"-------------------------------------"<<endl;
//            cout<<"这个单词是:"<<word<<endl;
//            cout<<"-------------------------------------"<<endl;
            cout<<transform(word, trans_map);   //打印输出
        }
        cout<<endl;     //完成一行的转换
    }
}

int main()
{
    ifstream map_file,input;
    map_file.open("map_file.txt");
    input.open("input.txt");

    word_transform(map_file, input);

    map_file.close();
    input.close();

    return 0;
}

这个

bulidMap(ifstream &map_file)
里面的return记得要放到while循环的外面哦

我可是为了这个吃了不少苦头。

PS:放假了,我估计最多把今天写完了,明天开始大概要停更了,大家不要停止学习哦,一起加油,一起努力,这本书我还是会看下去的,只是博客可能更不了了。

【足迹C++primer】38、关联容器操作(2),布布扣,bubuko.com

时间: 2024-10-29 10:47:55

【足迹C++primer】38、关联容器操作(2)的相关文章

【足迹C++primer】38、关联容器操作(1)

关联容器操作 关联容器中还定义了三个类型,如下: set<string>::value_type v1; //这个v1是string类型 set<string>::key_type v2; //这个v2是string类型 map<string, int>::value_type v3; //v3是pair类型pair<const string, int> map<string, int>::key_type v4; //v4是string类型 m

c++ primer 10 关联容器

关联容器和顺序容器的本质差别在于:关联容器通过键(key)存储和读取元素,顺序容器则通过元素在容器中的位置顺序存储和访问元素 关联容器类型 map 关联数组:元素通过键来存储和读取 set 大小可变的集合,支持通过键实现的快速读取 multimap 支持同一个键多次出现的 map 类型 multiset 支持同一个键多次出现的 set 类型 pair类型 pair是一种模版类型,在创建pair对象,必须提供两个类型名. 头文件 utility pairs 类型提供的操作 pair<T1, T2>

《C++primer(第五版)》学习之路-第十一章:关联容器

[ 声明:版权所有,转载请标明出处,请勿用于商业用途.  联系信箱:[email protected]] 11.1 使用关联容器 1. 关联容器类型 按关键字有序保存元素 map                    关联数组,保存关键字-值对 set                      关键字即值,即只保存关键字的容器 multimap            关键字可重复出现的map multiset              关键字可重复出现的set 无序集合 unordered_ma

C++ Primer笔记7_STL之关联容器

关联容器 与顺序容器不同,关联容器的元素是按关键字来访问和保存的.而顺序容器中的元素是按他们在容器中的位置来顺序保存的. 关联容器最常见的是map.set.multimap.multiset map的元素以键-值[key-value]对的形式组织:键用作元素在map中的索引,而值则表示所存储和读取的数据. set仅包含一个键,并有效的支持关于某个键是否存在的查询. pair类型 首先介绍下pair,pair定义在utility头文件中,一个pair保存两个数据成员,类似容器,pair是一个用来生

CH11 关联容器

关联容器与顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的,而顺序容器是按它们在容器中的位置来顺序保存和访问的.两个主要的关联容器:map和set map 中的元素的是一个key-value对:关键字是用来索引值关联的数据.set:每个关键字值包含一个关键字. 关联容器类型: map 保存key-value  map<key,value> set 保存关键字key set<key> multimap 关键字可以重复出现的map multiset 关键字可以重复出现的

关联容器——map、set

map类型通常被称为关联数组,与正常数组类似,不同之处在于其下标不必是整数.我们通过一个关键字而不是位置来查找值(键值对). 与之相对,set就是关键字的简单集合.当只是想知道一个值是否存在时,set是最有用的. 类似顺序容器,关联容器也是模板,为了定义一个map,我们必须指定关键字和值得类型.例:map<string,int>test;一个test的空map,关键字是string.值是int的.set<string> e={"hello"};设置关键字集合,类

关联容器详解(一)

本文为对<C++ primer (中文版第五版)>中有关关联容器的讲解和网上大神们的博客整理而成. 关联容器和顺序容器的根本不同在于:关联容器中的元素是按关键字来保存和访问的,而顺序容器中的元素则是按它们在容器中的位置来顺序保存和访问的.顺序容器有vector.deque.list.forward_list.array.string等,更多详情,可见melonstreet的博客. 关联容器支持高效的关键字查找和访问.主要的关联容器类型是map和set,其中map中的元素是一些关键字-值(key

第11章 关联容器

map,管理数组,存储“关键字-值” set,简单集合,存储“关键字” 四个关联容器的头文件map.set.unordered_map.unordered_set 关联容器有8种,特点如下: 每个容器都是set或者map 分为允许关键字重复(multi)和不允许关键字重复 顺序保存和无序保存(unordered,哈希函数组织的结构) unordered_multiset是一个允许关键字重复,元素无序保存的集合 set是一个要求关键字不重复,元素有序保存的集合 map<string, size_t

STL2——关联容器

关联容器 关联容器支持通过键(key)来高效地查找和读取元素.两个基本的关联容器是map和set,map的元素以键-值对形式组织,键用做索引,值表示存储和读取的数据,set包含一个键,并有效地支持关于某个键是否存在的查询. 引言:pair类型 #include<utility> pair<int,int>p; p.first=5; p.second=6; pair<int,int>p2; p2=make_pair(5,7); pair<int,int>p3(