第十一章 关联容器 学习笔记

11.1、使用关联容器

//11.4单词计数程序,程序扩展,忽略大小写和标点
#include<iostream>
#include<fstream>
#include<map>
#include<string>
#include<algorithm>

using namespace std;

string &trans(string &s)
{
    for(int p = 0; p < s.size(); ++p){
        if(s[p] >= 'A' && s[p] <= 'Z')
            s[p] -= ('A' - 'a');
        else if(s[p] == ',' || s[p] == '.')
            s.erase(p, 1);      //从p开始删除一个字符
    }
    return s;
}

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

    map<string, size_t> word_count;     //string 到 count 映射
    string word;
    while(in >> word)
        ++word_count[trans(word)];      //单词出现次数加一
    
    for(const auto &w : word_count)     //对map中的每个元素
        //打印结果
        cout << w.first << "出现了" << w.second << "次" << endl;
    
    return 0;
}
//11.9 定义一个map,将单词与一个行号的list关联,list中保存的是单词所出现的行号。
#include<iostream>
#include<fstream>
#include<sstream>
#include<map>
#include<list>
#include<string>
#include<algorithm>

using namespace std;

string &trans(string &s)
{
    for(int p = 0; p < s.size(); ++p){
        if(s[p] >= 'A' && s[p] <= 'Z')
            s[p] -= ('A' - 'a');
        else if(s[p] == ',' || s[p] == '.')
            s.erase(p, 1);      //从p开始删除一个字符
    }
    return s;
}

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

    map<string, list<int>> word_lineno;     //单词到行号的映射
    string line;
    string word;
    int lineno = 0;
    while(getline(in, line)){       //读取一行
        lineno++;                   //行号增加
        istringstream l_in(line);   //构造字符串流,读取单词
        while(l_in >> word){
            trans(word);
            word_lineno[word].push_back(lineno);       //添加行号
        }
    }

    for(const auto &w : word_lineno){       //打印单词行号
        cout << w.first << "所在行:";
        for(const auto &i : w.second)
            cout << i << " ";
    cout << endl;
    }
    return 0;
}
multiset<Sales_data, decltype(compareIsbn)*> bookstore(compareIsbn);
//等价于
typedef bool (*pf)(const Sales_data &, const Sales_data &);
multiset<Sales_data, pf> bookstore(compareIsbn);

pair类型(头文件utility)

//练习11.12、编写程序,读入string 和 int的序列,将每个string和int存入一个pair中,pair保存在一个vector中
#include<iostream>
#include<fstream>
#include<utility>
#include<vector>
#include<string>
#include<algorithm>

using namespace std;

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

    vector<pair<string, int>> data;     //pair的vector
    string s;
    int v;
    while(in >> s && in >> v)           //读取一个字符串和一个整数
        //三种不同的方式
        data.push_back({s, v});
        //data.push_back(pair<string, int>(s, v));
        //data.push_back(make_pair(s, v));

    for(const auto &d : data)           //打印单词行号
        cout << d.first << " " << d.second << endl;

    return 0;
}

11.3、关联容器操作

检测insert的返回值

insert(或emplace)返回的值依赖于容器类型和参数。对于不包含重复关键字的容器,添加单一元素的insert和emplace版本返回一个pair,告诉我们插入操作是否成功。pair的first成员是一个迭代器,指向具有给定关键字的元素。second是一个bool值,指出元素是否插入成功还是已经存在容器中。

删除元素

map的下标操作

使用map下标操作的返回值

对一个map进行下标操作时,会获得一个mapped_type对象;但当解引用一个map迭代器时,会得到一个value_type对象。

访问元素

//练习11.31
#include<iostream>
#include<string>
#include<map>
#include<algorithm>

using namespace std;

void remove_author(multimap<string,string> &books,
                    const string &author)
{
    auto pos = books.equal_range(author);   //查找给定作者范围
    if(pos.first == pos.second)             //空范围,没有该作者
        cout << "没有" << author << "这个作者" << endl << endl;
    else
        books.erase(pos.first, pos.second); //删除该作者的所有著作
}

void print_books(multimap<string, string> &books)
{
    cout << "当前书目包括:" << endl;
    for(auto &book : books)                 //遍历所有书籍,打印之
        cout << book.first << ", 《" << book.second << "》" << endl;
    cout << endl;
}

int main(int argc, char *argv[])
{
    multimap<string, string> books;
    books.insert({"Barth, John", "Sot-Weed Factor"});
    books.insert({"Barth, John", "Lost in the Funhouse"});
    books.insert({"金庸", "射雕英雄传"});
    books.insert({"金庸", "天龙八部"});

    print_books(books);
    remove_author(books, "张三");
    remove_author(books, "金庸");
    print_books(books);

    return 0;
}
#include <map>
#include <string>
#include <fstream> 
#include <iostream>
#include <sstream>

using namespace std;

map<string, string> buildMap(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)                //检查是否有转换规则
            trans_map[key] = value.substr(1);   //跳过前导空格
        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;                   //否则返回原string
}

void word_transform(ifstream &map_file, ifstream &input)
{
    auto trans_map = buildMap(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 << transform(word, trans_map);     //打印输出
        }
        cout << endl;                               //完成一行的转换
    }
}

int main(int argc, const char *argv[])
{
    if(argc != 3)
        throw runtime_error("wrong numbei 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;
}

无序容器

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值