【C++ Primer】【学习笔记】【第十章】关联容器之:map类型

原创 2015年01月13日 00:25:44
使用map对象,则需要包含map头文件。在定义map对象时,必须分别指明键和值的类型。

一、map对象的定义
map的构造函数如下:
构造函数
说明
map<k, v> m;
创建一个名为m的空map对象,其键和值的类型分别为k和v。
map<k, v> m(m2);
创建m2的副本m,m与m2必须有相同的键类型和值类型。
map<k, v> m(b, e);
创建map类型的对象m,存储迭代器b和e标记的范围内所有元素的副本。元素的类型必须能转换为pair<const k, v>。
注:对于键类型,唯一的约束就是必须支持 < 操作符。

二、map定义的类型
map类类型成员
说明
map<K, V>::key_type
在map容器中,用作索引的键的类型。
map<K, V>::mapped_type
在map容器中,键所关联的值的类型。
map<K, V>::value_type
一个pair类型,它的first元素具有const map<K, V>::key_type类型,而second元素则为map<K, V>::mapped_type类型。
注:map迭代器返回value_type类型的值,而下标操作符返回一个mapped_type类型的值。

三、map对象插入元素
插入方法
说明
m.insert(e)
e是map类型对应的value_type类型的值。如果键(e.first)不在m中,则插入一个值为e.second的新元素;如果键(e.first)在m中已存在,则保持m不变。该函数返回一个pair类型的对象,包含指向键为e.first元素的map迭代器,以及一个bool类型的对象,表示是否插入了该元素。
m.insert(beg, end)
beg和end是标记元素范围的迭代器,其中的元素必须为m.value_type类型的键-值对。对于这些元素,如果其键在m中不存在,则将该键对应的元素插入m。返回值为void。
m.insert(iter, e)
e是map类型对应的value_type类型的值。如果(e.first)不在m中,则插入一个值为e.second的新元素,并以迭代器iter为起点搜索新元素存储的位置。该函数返回一个迭代器,指向m中具有给定键的元素。

四、map元素的查找和访问
查询方法
说明
m.count(k)
返回m中k的出现次数。返回值只能是0或者1,因为map容器只允许一个键对应一个实例。
m.find(k)
如果m容器中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器。

五、map元素的删除
删除方法
说明
m.erase(k)
删除m中键为k的元素。返回size_type类型的值,表示删除的元素个数。
m.erase(p)
从m中删除迭代器p所指向的元素。p必须指向m中确实存在的元素,而且不能等于m.end()。返回void类型。
m.erase(b, e)
从m中删除一段范围内的元素,b和e必须标记m中的一段有效范围:即b和e都必须指向m中的元素或最后一个元素的下一个位置。而且,b和e要么相等(此时删除的范围为空),要么b所指向的元素必须出现在e所指向的元素之前。返回void类型。

六、map容器的遍历
使用迭代器进行遍历,如:map<string, int>::const_iterator map_it = word_count.begin();
注:在使用迭代器遍历map容器时,迭代器指向的元素按键的升序排列。


习题10.9:统计单词出现的次数

#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include <map>
using namespace std;

int main()
{
    map<string, int> word_count;
    string word;

    cout << "Enter some words(Ctrl + Z or Ctrl + D to end):" << endl;

    while (cin >> word)
    {
        ++word_count[word];
    }

    cout << "word\t\t" << "times" << endl;

    for (map<string, int>::iterator it = word_count.begin(); it != word_count.end(); ++it)
    {
        cout << it->first << "\t\t" << it->second << endl;
    }

    return 0;
}
[chapter10]$ ./a.out 
Enter some words(Ctrl + Z or Ctrl + D to end): 
abc abc ab def 
word times 
ab 1 
abc 2 
def 1

习题10.12:统计单词出现的次数(insert函数实现)

#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include <map>
using namespace std;

int main()
{
    map<string, int> word_count;
    string word;

    cout << "Enter some words(Ctrl + Z or Ctrl + D to end):" << endl;

    while (cin >> word)
    {
        pair<map<string, int>::iterator, bool> ret = word_count.insert(pair<string, int>(word, 0));
        ++ret.first->second;
    }

    cout << "Word\t\t" << "times" << endl;

    for (map<string, int>::iterator it = word_count.begin(); it != word_count.end(); ++it)
    {
        cout << it->first << "\t\t" << it->second << endl;
    }

    return 0;
}
[chapter10]$ ./a.out 
Enter some words(Ctrl + Z or Ctrl + D to end): 
aaa bbb ccc ddd aaa bbb ccc eee 
Word times 
aaa 2 
bbb 2 
ccc 2 
ddd 1 
eee 1

习题10.17:单词转换

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <map>
#include <stdexcept>
using namespace std;

ifstream & open_file(ifstream &in, const string &file)
{
    in.close();
    in.clear();
    in.open(file.c_str());
    return in;
}

int main(int argc, char **argv)
{
    map<string, string> trans_map;
    string key, value;

    if (argc != 3)
    {
        throw runtime_error("wrong number of arguments");
    }

    ifstream map_file;
    if (!open_file(map_file, argv[1]))
    {
        throw runtime_error("no transformation file");
    }

    while (map_file >> key >> value)
    {
        trans_map.insert(make_pair(key, value));
    }

    ifstream input;
    if (!open_file(input, argv[2]))
    {
        throw runtime_error("no input file");
    }
   
    string line;
    while (getline(input, line))
    {
        istringstream stream(line);
        string word;
        bool firstword = true;
        while (stream >> word)
        {
            map<string, string>::const_iterator map_it = trans_map.find(word);
            if (map_it != trans_map.end())
            {
                word = map_it->second;
            }

            if (firstword)
            {
                firstword = false;
            }
            else
            {
                cout << "  ";
            }
            cout << word;
        }
        cout << endl;
    }

    return 0;
}
[chapter10]$ ./a.out 
terminate called after throwing an instance of 'std::runtime_error' 
what(): wrong number of arguments 
Aborted (core dumped) 
[chapter10]$ ./a.out dic daa 
terminate called after throwing an instance of 'std::runtime_error' 
what(): no transformation file 
Aborted (core dumped)
[chapter10]$ ./a.out dict.txt aaa 
terminate called after throwing an instance of 'std::runtime_error' 
what(): no input file 
Aborted (core dumped)
[chapter10]$ cat dict.txt
i       I
love    LOVE
you     YOU
[chapter10]$ cat input.txt
i love you
i love you
[chapter10]$ ./a.out dict.txt input.txt
I  LOVE  YOU
I  LOVE  YOU

习题10.18:姓氏名字

[chapter10]$ cat exercise_10.18_name.cpp
#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;

int main()
{
    map<string, vector<string> > children;
    string surname, childname;

    // Read: Surname + childname1 + childname2 + ... + childnamen
    do
    {
        cout << "Enter surname(Ctrl + Z or Ctrl + D to end):" << endl;
        cin >> surname;
        if (!cin)
        {
            break;
        }

        vector<string> chd;
        pair<map<string, vector<string> >::iterator, bool> ret = children.insert(make_pair(surname, chd));

        if (!ret.second)
        {
            cout << "repeated surname: " << surname << endl;
            continue;
        }

        cout << "Enter children's name(Ctrl + Z or Ctrl + D to end):" << endl;
        while (cin >> childname)
        {
            ret.first->second.push_back(childname);
        }
        cin.clear();
    } while(cin);

    cin.clear();

    cout << "Enter a surname to search:" << endl;
    cin >> surname;

    map<string, vector<string> >::iterator iter = children.find(surname);
    if (iter == children.end())
    {
        cout << "no this surname: " << surname << endl;
    }
    else
    {
        cout << "children: " << endl;
        vector<string>::iterator it = iter->second.begin();
        while (it != iter->second.end())
        {
            cout << *it++ << endl;
        }
    }

    return 0;
}
[chapter10]$ ./a.out
Enter surname(Ctrl + Z or Ctrl + D to end):
123      
Enter children's name(Ctrl + Z or Ctrl + D to end):
a b c d e f g
Enter surname(Ctrl + Z or Ctrl + D to end):
Enter a surname to search:
123
children:
a
b
c
d
e
f
g

习题10.19:姓氏名字生日

#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;

int main()
{
    map<string, vector<pair<string, string> > > children;
    string surname, childname, birthday;

    // Read: Surname + childname1&birthday1 + childname2&birthday2 + ... + childnamen&birthdayn
    do
    {
        cout << "Enter surname(Ctrl + Z or Ctrl + D to end):" << endl;
        cin >> surname;
        if (!cin)
        {
            break;
        }

        // child's name and birthday
        vector<pair<string, string> > chd;
        pair<map<string, vector<pair<string, string> > >::iterator, bool> ret = children.insert(make_pair(surname, chd));

        if (!ret.second)
        {
            cout << "repeated surname: " << surname << endl;
            continue;
        }

        cout << "Enter children's name and birthday(Ctrl + Z or Ctrl + D to end):" << endl;
        while (cin >> childname >> birthday)
        {
            ret.first->second.push_back(make_pair(childname, birthday));
        }
        cin.clear();
    } while(cin);

    cin.clear();

    while (1)
    {
        cout << "Enter a surname to search:" << endl;
        cin >> surname;
    
        map<string, vector<pair<string, string> > >::iterator iter = children.find(surname);
        if (iter == children.end())
        {
            cout << "no this surname: " << surname << endl;
        }
        else
        {
            cout << "children\t\tbirthday" << endl;
            vector<pair<string, string> >::iterator it = iter->second.begin();
            while (it != iter->second.end())
            {
                cout << it->first << "\t\t" << it->second << endl;
                it++;
            }
        }
    }

    return 0;
}
[chapter10]$ ./a.out 
Enter surname(Ctrl + Z or Ctrl + D to end):
123
Enter children's name and birthday(Ctrl + Z or Ctrl + D to end):
a 11111111 b 22222222
Enter surname(Ctrl + Z or Ctrl + D to end):
Enter a surname to search:
123
children                birthday
a               11111111
b               22222222
Enter a surname to search:
456
no this surname: 456
Enter a surname to search:
^C


相关文章推荐

Valid Number 判断一个string是不是有效地数字表达式 @LeetCode

这道题看了看网上的解法,很多都做得很麻烦。其实我觉得,这道题就是考察正则表达式。 package Level2; /** * Valid Number * * Validate if...

【转载】隐马尔科夫模型HMM自学

【转载】隐马尔科夫模型HMM自学   2013-10-08 17:06:17|  分类: 采摘她家|举报|字号 订阅 本文转载自旺齐齐《隐马尔科夫模型HMM自学》 ...
  • wowotuo
  • wowotuo
  • 2014年11月04日 14:12
  • 1028

【C++ Primer】【学习笔记】【第十章】关联容器之:pair类型

pair类型和容器一样,也是一种模板类型。 一、pair类型对象的创建和初始化 创建pair对象时,必须提供两个类型名。如下: pair anon;            // 调用默认...
  • jay_yin
  • jay_yin
  • 2015年01月09日 15:14
  • 296

【C++ Primer】【学习笔记】【第十章】关联容器之:set类型

一、set容器定义 set容器支持大部分的map操作,但如下两种操作除外: 1、set不支持下标操作; 2、set没有定义mapped_type类型。 注:set存储的元素仅仅是键,而不存储所...
  • jay_yin
  • jay_yin
  • 2015年02月06日 16:53
  • 367

【C++ Primer】【学习笔记】【第十章】关联容器之:multimap和multiset类型

一、基本概念 map和set容器,一个键只能对应一个实例;而multimap和multiset容器则允许一个键对应多个实例。 multimap类型使用的头文件与map类型一样,均为map;同样地,...
  • jay_yin
  • jay_yin
  • 2015年02月10日 15:09
  • 230

关联容器 - 1【C++ Primer 学习笔记 - 第十章】

关联容器的类型: 1、map    关联数组,元素通过键来存储和读取,以键值(key-value)对的形式组织 2、set      大小可变的集合,支持通过键实现的快速读取 3、multima...

【C++ Primer】【学习笔记】【第十章】关联容器之:文本查询程序

textquery.h: #include #include #include #include class TextQuery { public: typedef std::ve...
  • jay_yin
  • jay_yin
  • 2015年02月15日 18:00
  • 235

C++ Primer复习和学习笔记 第十章 关联容器

/*翻译程序:输入两个文本,一个是源文件,一个是翻译文件。使用方式如下; 命令名 源文件名 翻译文件 运行完程序之后,写入一个vector中,然后写入文件中。 */ #include ...

c++ primer读书笔记-第十章 关联容器

c++ primer读书笔记-第十章 关联容器关联容器和顺序容器的本质差别在于:关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存储和访问元素。 关联容器(Associ...

c++ primer(第五版)学习笔记及习题答案代码版(第十一章)关联容器

笔记较为零散,都是自己不熟悉的知识点。 习题答案至于一个.cc 中,包含Chapter7.h头文件,读入文件包括./test ./rules .需要演示某一题直接修改 #define NUM****...
  • refuil
  • refuil
  • 2016年05月24日 16:31
  • 3629
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【C++ Primer】【学习笔记】【第十章】关联容器之:map类型
举报原因:
原因补充:

(最多只允许输入30个字)