zoukankan      html  css  js  c++  java
  • C++primer笔记之关联容器

    在这一章中,有以下的几点收获:

    1、pair类型的使用相当频繁,如果需要定义多个相同的pair类型对象,可考虑利用typedef简化其声明:

    typedef pair<string, string> A;这样,在后面的使用中就可以直接用A来代替前面繁琐的书写。

    2、三种方法创建pair对象:

    (1)第一种方法:使用函数make_pair()

    pair<string, string> spair;

    string first, last;

    while(cin >> first >> last) {

      spair = make_pair(first, last);

    }

    (2)第二种方法:可以调用vector的构造函数

    spair = pair<string, string> (first, last);

    (3)第三种方法:由于pair的数据成员是公有的,所以可以直接输入

    while(cin >> spair.first >> spair.last) { //}

    三种方法个人用起来的话是第一种好用些,看个人喜好。

    3、map定义的类型

    map对应的元素是键-值对,在学习map接口时,警记value_type是pair类型,键是key_type类型,为const,不可修改,而值是mapped_type类型,可以修改。如下:

    map<K,V>::key_type       键的类型

    map<k,V>::mapped_type 值得类型

    map<k,V>::value_type     pair类型,first元素为const map<K,V>::key_type类型,second元素为map<K,V>::mapped_type类型

    4、使用下标访问map对象

    使用下标访问map与使用下标访问数组或vector的行为截然不同,用下标访问不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标值。

    5、可以用insert代替下标运算,既简洁又紧凑

    word.insert(map<string, int>::value_type("anna", 1));

    其中红色部分代码可以用以下的两种方法代替:

    word.insert(make_pair("anna",1));

    typedef map<string, int>::value_type valType;

    word.insert(valType("anna",1));

    6、单词统计程序的两个版本:

    第一版本:采用下标

    1 string word;
    2 map<string, int> wordCount;
    3 
    4 //第一版本
    5 while(cin >> word) {
    6     ++ wordCount[word];
    7 }

    第二版本:采用insert,利用返回值的第二个bool值来判断元素是否插入

     1 string word;
     2 map<string, int> wordCount;
     3 
     4 //第二版本
     5 while(cin >> word) {
     6     pair< map<string, int>::iterator, bool > ret =
     7     wordCount.insert(make_pair(word,1));           //!!!注意此句的表达
     8    if (ret.second == false) //表明没有插入数据,map中已经存在着相应的单词
     9         ++wordCount[word];
    10 }    

    7、与map容器不一样,set容器的每个键对应的元素是唯一的,不可重复。
    8、在multimap和multiset中查找元素

    可以用三种策略来解决查找问题:

    第一种策略:使用find和count操作:

    count函数求出某键出现的次数,而find操作则返回一个迭代器,指向第一个拥有正在查找的键的实例:

     1 multimap<string, string> smmap; //创建作者和书名对应的multimap对象
     2 string searchName("Wang");         //搜索的作者名
     3 
     4 //第一种方法:采用find和count操作    
     5 typedef multimap<string, string>::size_type sz_type;
     6 sz_type nCount = smmap.count(searchName); //得到searchName键对应的项的个数
     7 multimap<string, string>::iterator it = smmap.find(searchName);
     8     
     9 for (sz_type si = 0; si != nCount; ++ si, ++ it)
    10     cout << it->second << endl;

    第二种策略:采用面向迭代器的解决方案:
    采用有关关联迭代器的操作:lower_bound和upper_bound

    1 //第二种方法:采用面向迭代器的解决方案
    2 typedef multimap<string, string>::iterator iter;
    3 iter beg = smmap.lower_bound(searchName);
    4 iter end = smmap.upper_bound(searchName);
    5 while(beg != end) {
    6     cout << beg->second << endl;
    7     ++ beg;
    8 }

    第三种策略:采用equal_range函数
    调用equal_range来代替upper_bound和lower_bound函数的效果是一样的

    1 //第三种方法:采用equal_range函数
    2 typedef multimap<string, string>::iterator iter;
    3 pair<iter, iter> pos = smmap.equal_range(searchName);
    4 while (pos.first != pos.second) {
    5 //pos是一对迭代器,pos.first是第一个迭代器所关联的实例,而pos.first->second是该实例所对应的值
    6     cout << pos.first->first << "		" << pos.first->second << endl; 
    7     ++ pos.first;
    8 }

    9、容器的综合应用:文本查询程序
    要求:给定一个文本文件,允许用户从该文件中查找单词,查询的结果是该单词出现的次数,并列出每次出现所在的行,如果某单词在同一行中多次出现,程序将只显示该行一次,行号按升序显示:

    下面是程序的代码实现,详细实现细节可参考书本,首先看.h文件:

     1 #ifndef _TEXTQUERY_H
     2 #define _TEXTQUERY_H
     3 
     4 /************************************************************************/
     5 /*   单词查找程序
     6 /*   指定任意文本,并在其中查找单词
     7 /*   结果为该单词出现的次数,并列出每次出现的行
     8 /*   如果该单词在同一行中出现多次,将只显示该行一次,行号按升序显示
     9 /************************************************************************/
    10 class TextQuery {
    11 public:
    12     typedef vector<string>::size_type line_no; //行号
    13     void read_file(ifstream &is) {   //从文件读入一行,并创建每个单词对应行号的map容器
    14         store_file(is);
    15         build_map();
    16     }
    17     set<line_no> run_query(const string &) const; //返回包含string对象的所有行的行号
    18     string text_line(line_no) const; //返回某行号所对应的文本行
    19 private:
    20 
    21     void store_file(ifstream &);  //读入文件的每一行并存入vector中
    22     void build_map(); //将每一行分解成各单词,同时记录该单词出现的行号
    23 private:
    24     vector<string> lines_of_text;
    25     map < string, set<line_no> > word_map;
    26 };
    27 
    28 // void TextQuery::read_file(ifstream &is)
    29 // {
    30 //     store_file(is);
    31 //     build_map();
    32 // }
    33 
    34 set<TextQuery::line_no> TextQuery::run_query(const string &str) const
    35 {
    36     map< string, set<line_no> >::const_iterator loc = word_map.find(str);
    37     if (loc == word_map.end())
    38         return set<line_no>();  //没有找到,则返回空的set集
    39     else
    40         return loc->second;
    41 }
    42 
    43 string TextQuery::text_line(line_no line) const
    44 {
    45     if (line < lines_of_text.size())
    46         return lines_of_text[line];
    47     throw out_of_range("line number out of range");
    48 }
    49 
    50 void TextQuery::store_file(ifstream &infile)
    51 {
    52     string line;
    53     while(getline(infile, line))
    54         lines_of_text.push_back(line);
    55 }
    56 
    57 void TextQuery::build_map()
    58 {
    59     for(line_no linenum = 0; linenum != lines_of_text.size(); ++ linenum) {
    60         istringstream issrem(lines_of_text[linenum]);
    61         string word;
    62         while (issrem >> word) {
    63             word_map[word].insert(linenum); //下标插入法
    64         }
    65     }
    66 }
    67 
    68 #endif//_TEXTQUERY_H

    下面是.cpp文件

     1 #include "stdafx.h"
     2 #include <iostream>
     3 #include <map>
     4 #include <set>
     5 #include <vector>
     6 #include <sstream>
     7 #include <fstream>
     8 #include <string>
     9 
    10 using namespace std;
    11 #include "TextQuery.h"
    12 #include "fileio.h"
    13 
    14 /************************************************************************/
    15 /*  文本查询程序(TextQuery.h)
    16 /*  Author:bakari  Date:2013.9.20
    17 /************************************************************************/
    18 
    19 void print_result(const set<TextQuery::line_no> &locs,
    20                   const string &s, const TextQuery &file);//打印结果
    21 string make_plural(size_t size, const string &str, const string &endstr);//根据size的值打印单数还是复数
    22 
    23 int main(int argc, char **argv)
    24 {
    25     ifstream infile;
    26     
    27     if (argc < 2 || !open_file(infile,argv[1])) {
    28         cerr << "no input file" << endl;
    29         return EXIT_FAILURE;
    30     }
    31     TextQuery tq;
    32     tq.read_file(infile);
    33     
    34     while(true) {
    35         cout << "enter word to look for or q to quit!" << endl;
    36         string s;
    37         cin >> s;
    38         if (!cin || s == "q")
    39             break;
    40         set<TextQuery::line_no> locs = tq.run_query(s);
    41         print_result(locs, s, tq);
    42     }
    43     return 0;
    44 }
    45 
    46 void print_result(const set<TextQuery::line_no> &locs,
    47                   const string &s, const TextQuery &file)
    48 {
    49     typedef set<TextQuery::line_no> line_num;
    50     line_num::size_type size = locs.size(); //记录locs中每个单词出现的总次数 !!!注意表达
    51     if (!size) { //没有该单词出现
    52         cout << "no this word!" << endl;
    53         exit(EXIT_FAILURE);
    54     }
    55 
    56     cout << s << " occurs " << size << make_plural(size, " time", "s") << endl;
    57     for (line_num::const_iterator iter = locs.begin(); iter != locs.end(); ++iter) {
    58         cout << "	(line " << *iter + 1 << ") ";
    59         cout << file.text_line(*iter) << endl;
    60     }
    61 
    62 }
    63 
    64 string make_plural(size_t size, const string &str, const string &endstr)
    65 {
    66     return (size == 1)?str : str + endstr;
    67 }

    程序运行结果:

  • 相关阅读:
    【知识强化】第五章 中央处理器 5.3 数据通路的功能和基本结构
    【知识强化】第五章 中央处理器 5.5 指令流水线
    【知识强化】第五章 中央处理器 5.4 控制器的功能和工作原理
    【知识强化】第二章 数据的表示和运算 2.4 算术逻辑单元ALU
    【知识强化】第二章 数据的表示和运算 2.3 浮点数的表示与运算
    【知识强化】第五章 中央处理器 5.2 指令执行过程
    【知识强化】第七章 输入/输出系统 7.3 I/O接口
    【知识强化】第七章 输入/输出系统 7.2 外部设备
    【知识强化】第三章 存储系统 3.7 虚拟存储器
    【知识强化】第七章 输入/输出系统 7.1 I/O系统基本概念
  • 原文地址:https://www.cnblogs.com/bakari/p/3332230.html
Copyright © 2011-2022 走看看