C++ Primer 学习笔记_36_STL实践与分析(10)--map类型(下

STL实践与分析

--map类型(下)

六、查找并读取map中的元素

map容器提供了两个操作:count和find,用于检查某个键是否存在而不会插入该键:


不修改map对象的查询


m.count(k)


返回m中k的出现次数


m.find(k)


如果m容器中存在k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端的迭代器

1、使用count检查map对象中某键是否存在

因为map容器只允许一个键对应一个实例,所以,对于map对象,count成员的返回值只能是1或0。

如果返回值非0,则可以使用下标操作符来获取该键所关联的值,而不必担心这样会在map容器中插入新元素:

    int occurs = 0;
    if (word_cnt.count("Dream"))
    {
        occurs = word_cnt["Dream"];
    }
    cout << occurs << endl;

2、读取元素而不插入元素

    int occurs = 0;
    map<string,int>::iterator iter = word_cnt.find("Dream");
    if (iter != word_cnt.end())
    {
        occurs = iter -> second;
    }
    cout << occurs << endl;
//P316 习题10.16
map<string,vector<int> > str_vec;
map<string,vector<int> >::iterator iter = str_vec.find("dream");

七、从map对象中删除元素


从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标记。b和e必须标记m中的一段有效范围:即b和e都必须指向m中的元素或最后一个元素的下一个位置。而且,b和e要么相等(此时删除的范围为空),要么b所指向的元素必须出现在e所指向的元素之前。返回void类型

    int remCount = 0;
    if (remCount = word_cnt.erase("Dream"))
    {
        cout << "Have removed " << remCount << " words" << endl;
    }
    else
    {
        cout << "Not found!" << endl;
    }

erase函数返回被删除元素的个数。对于map容器,该值必然是0或者1。如果返回0值,则表示该元素并不存在于map容器中。

八、map对象的迭代遍历

与其他容器一样,map同样提供了begin和end运算,以生成用于遍历整个容器的迭代器:

    cout << "First:\t\tSecond:" << endl;
    map<string,int>::iterator iter = word_cnt.begin();
    while (iter != word_cnt.end())
    {
        cout << iter -> first << "\t\t" << iter -> second << endl;
        ++ iter;
    }

或:

    cout << "First:\t\tSecond:" << endl;
    typedef map<string,int>::iterator mapIter;
    for (mapIter iter = word_cnt.begin(); iter != word_cnt.end(); ++iter)
    {
        cout << iter -> first << "\t\t" << iter -> second << endl;
    }

在使用迭代器遍历map容器时,迭代器指向的元素按照键的升序排列。

九、“单词转换”map对象

1、问题:

给出一个string对象,把它转换为另一个string对象。本程序的输入是两个文件。第一个文件包括了若干单词对,每对的第一个单词将出现在输入的字符串中,而第二个单词则是用于输出。本质上,这个文件提供的是单词转换的集合——在遇到第一个单词时,应该将之替换为第二个单词。第二个文件则提供了需要转换的文本。如果单词转换文件的内容是:

'em them
cuz because
gratz grateful
i I
nah no
pos supposed
sez said
tanx thanks
wuz was

2、测试样例

而要转换的文本是:

	nah i sez tanx cuz i wuz pos to
	not cuz i wuz gratz 

则程序将产生如下输出结果:

	no I said thanks because I was supposed to
	not because I was grateful

4、思路:

将被替换的单词作为键,而用作的替换的单词则作为其相应要替换的值。

5、程序:

#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
using namespace std;

int main()
{
    ifstream inFile("input1");
    string line,firWord,secWord;
    map<string,string> convMap;

    while (getline(inFile,line))
    {
        istringstream strItem(line);
        while (strItem >> firWord >> secWord)
        {
            convMap.insert(make_pair(firWord,secWord));
        }
    }

    inFile.close();
    inFile.clear();
    inFile.open("input2");

    string word;
    while (getline(inFile,line))
    {
        istringstream strItem(line);
        while (strItem >> word)
        {
            map<string,string>::iterator iter = convMap.find(word);
            if (iter != convMap.end())
            {
                cout << iter -> second << ' ';
            }
            else
            {
                cout << word << ' ';
            }
        }
        cout << endl;
    }
}
//附上书上的原程序
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;
}
//P319 习题10.18
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
using namespace std;

int main()
{
    typedef string Family;
    typedef vector<string> Names;
    map<Family,Names> pepMap;

    Family first;
    string second;
    ifstream inFile("input");
    while (inFile >> first >> second)
    {
        Names child;
        pair<map<Family,Names>::iterator,bool> res = pepMap.insert(make_pair(first,child));
        res.first -> second.push_back(second);
    }

    inFile.close();
    inFile.clear();
    inFile.open("test");

    string searchFamily;
    while (inFile >> searchFamily)
    {
        map<Family,Names>::iterator iter = pepMap.find(searchFamily);

        if (iter == pepMap.end())
        {
            cout << "NO this Family name" << endl;
        }
        else
        {
            cout << iter -> first << ":" << endl;
            Names::iterator itName = iter -> second.begin();
            while (itName != iter -> second.end())
            {
                cout << *itName << endl;
                ++ itName;
            }
            cout << endl;
        }
    }
}
时间: 2024-10-16 17:15:00

C++ Primer 学习笔记_36_STL实践与分析(10)--map类型(下的相关文章

C++ Primer 学习笔记_45_STL实践与分析(19)--泛型算法的结构

STL实践与分析 --泛型算法的结构 引言: 正如全部的容器都建立在一致的设计模式上一样,算法也具有共同的设计基础. 算法最主要的性质是须要使用的迭代器种类.全部算法都指定了它的每一个迭代器形參可使用的迭代器类型.比方,假设形參必须为随机訪问迭代器则可提供vector或 deque类型的迭代器,或者提供指向数组的指针.而其它容器的迭代器不能用在这类算法上. C++还提供了另外两种算法模式:一种模式由算法所带的形參定义;还有一种模式则通过两种函数命名和重载的规范定义. 一.算法的形參模式 大多数的

C++ Primer 学习笔记_46_STL实践与分析(20)--容器特有的算法

STL实践与分析 --容器特有的算法 与其它顺序容器所支持的操作相比,标准库为list容器定义了更精细的操作集合,使它不必仅仅依赖于泛型操作.当中非常大的一个原因就是list容器不是依照内存中的顺序进行布局的,不支持随即訪问,这样,在list容器上就不能使用随即訪问迭代器的算法,如sort等:还有其它的一些算法如:merge.remove.reverse和unique,尽管能够用在list上,但却付出了高昂的性能代价.因此标准库结合list的内部结构,编写出了更快算法: list容器特有的操作

C++ Primer 学习笔记_35_STL实践与分析(9)--map种类(在)

STL实践与分析 --map类型(上) 引: map是键-值对的集合. map类型通常能够理解为关联数组:能够通过使用键作为下标来获取一个值,正如内置数组类型一样:而关联的本质在于元素的值与某个特定的键相关联,而并不是通过元素在容器中的位置来获取. 一.map对象的定义 1.定义map对象时,必须分别指明键和值的类型: map<string,int> wordCnt; map的构造函数 map<K,V>m; 创建一个名为m的空对象,其键和值的类型分别为K和V map<K,V&

C++ Primer 学习笔记_43_STL实践与分析(17)--再谈迭代器【中】

STL实践与分析 --再谈迭代器[中] 二.iostream迭代[续] 3.ostream_iterator对象和ostream_iterator对象的使用 能够使用ostream_iterator对象将一个值序列写入流中,其操作过程与使用迭代器将一组值逐个赋值给容器中的元素同样: ostream_iterator<string> out_iter(cout,"\n"); istream_iterator<string> in_iter(cin),eof; wh

C++ Primer 学习笔记_29_STL实践与分析(3) --操作步骤集装箱(下一个)

STL实践与分析 --顺序容器的操作(下) 六.訪问元素 假设容器非空,那么容器类型的front和back成员将返回容器的第一个和最后一个元素的引用. [与begin和end的对照:] 1)begin和end返回容器类型的迭代器,而不是引用: 2)end返回容器最后一个元素的下一个位置的迭代器,而back返回容器的最后一个元素的引用! /* *必须保证该list容器非空! *假设容器为空,则if语句内的全部操作都是没有定义的! */ if (!iList.empty()) { list<int>

C++ Primer 学习笔记_41_STL实践与分析(15)--先来看看算法【下一个】

STL实践与分析 --初窥算法[下] 一.写容器元素的算法 一些算法写入元素值.在使用这些算法写元素时一定要当心.必须确保算法所写的序列至少足以存储要写入的元素. 1.写入输入序列的元素 写入到输入序列的算法本质上是安全的--仅仅会写入与指定输入范围数量同样的元素. 写入到输入序列的一个简单算法是fill函数: fill(iVec.begin(),iVec.end(),10); fill(iVec.begin(),iVec.begin()+iVec.size()/2,0); fill带有一对迭代

C++ Primer 学习笔记_45_STL实践与分析(19)--建筑常规算法

STL实践与分析 --泛型算法的结构 引言: 正如全部的容器都建立在一致的设计模式上一样,算法也具有共同的设计基础. 算法最主要的性质是须要使用的迭代器种类.全部算法都指定了它的每一个迭代器形參可使用的迭代器类型. 比方,假设形參必须为随机訪问迭代器则可提供vector或 deque类型的迭代器,或者提供指向数组的指针. 而其它容器的迭代器不能用在这类算法上. C++还提供了另外两种算法模式:一种模式由算法所带的形參定义;还有一种模式则通过两种函数命名和重载的规范定义. 一.算法的形參模式 大多

C++ Primer 学习笔记_44_STL实践与分析(18)--再谈迭代器【下】

STL实践与分析 --再谈迭代器[下] 三.反向迭代器[续:习题] //P355 习题11.19 int main() { vector<int> iVec; for (vector<int>::size_type index = 0; index != 10; ++index) { iVec.push_back(index); } for (vector<int>::reverse_iterator r_iter = iVec.rbegin(); r_iter !=

C++ Primer 学习笔记_40_STL实践与分析(14)--概要、先来看看算法【上】

STL实践与分析 --概述.初窥算法[上] 标准库容器定义的操作很少.并没有给容器加入大量的功能函数.而是选择提供一组算法,这些算法大都不依赖特定的容器类型,是"泛型"的.可作用在不同类型的容器和不同类型的元素上! 所谓泛型算法:一是由于它们实现共同的操作,所以称之为"算法";而"泛型"指的是它们可以操作在多种容器类型上--不但可作用于vector或list这些标准库类型,还可用在内置数组类型.甚至其它类型的序列上,仅仅要自己定义的容器类型仅仅要