笔记:C++学习之旅---关联容器

来源:互联网 发布:2万钱网络大电影 编辑:程序博客网 时间:2024/06/06 06:44
笔记:C++学习之旅---关联容器

      关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的。与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的
      关联容器支持高效的关键字查找和访问。两个主要的关联容器类是mapset
map中的元素是一些关键字的-值(key-value)对:关键字起到索引的作用,值则表示与索引相关联的数据。set中每个元素只包含一个关键字:set支持高效的关键字查询操作--检查一个给定关键字是否在set中。

例子:
一个经典的使用关联数组的例子是单词计数程序:
#include<iostream>
#include<string>
#include<map>
#include<set>
usingnamespacestd;

intmain()
{
            map<string,size_t> word_count;
            stringword;
            set<string> exclude = {"The","But","And","Or","An","A","the","but","and","or","an","a"};//忽略的单词
            cout <<"请输入一串英文单词\n";
            while(cin >> word)
            {
                        if(word =="#")
                                    break;
                        if(exclude.find(word) == exclude.end())
                        {
                                    ++word_count[word];
                        }
            }
                        for(constauto&w : word_count)
                        cout << w.first <<" occurs "<< w.second << ((w.second > 1) ?" times ":" time ") << endl;

            return0;
}
练习11.3 11.4:
编写你自己的单词计数程序,忽略大小写和标点。如,"example"“example,”和“Example”应该递增相同的计数器。

#include<iostream>
#include<map>
#include<string>
#include<algorithm>
usingnamespacestd;

voidprint(map<string,size_t> &map)
{
            for(auto&m : map)
                        cout <<m.first<<":"<<m.second<<endl;
}
voidword_count_pro(map<string,size_t> &m)
{
            stringword;
            cout <<"请输入一串英文单词\n";
            while(cin >> word)
            {
                        if(word =="#")
                                    break;
                        for(auto&ch : word)
                                    ch = towlower(ch);//大小写转换;
                        word.erase(remove_if(word.begin(), word.end(), ispunct), word.end());//ispunct 判断是否为标点符号或者特殊字符进行删除;
                        ++m[word];
            }
            print(m);
}
intmain()
{
            map<string,size_t> map;
            word_count_pro(map);
            return0;
}

关联容器的概述

#include<iostream>
#include<vector>
#include<map>
#include<set>
usingnamespacestd;

intmain()
{
            vector<int> vec;
            for(vector<int>::size_typei = 0; i != 10; ++i)
            {
                        vec.push_back(i);
                        vec.push_back(i);
            }
            set<int> iset(vec.cbegin(), vec.cend());
            multiset<int> miset(vec.cbegin(), vec.cend());
            cout << vec.size() << endl;//20
            cout << iset.size() << endl;//10
            cout << miset.size() << endl;//20
            return0;
}

练习11.7:
定义一个map,关键字是家庭的姓,值是一个vector,保存家中孩子(们)的名。编写代码,实现添加新的家庭以及向已有家庭中添加新的孩子。
#include<iostream>
#include<vector>
#include<string>
#include<map>
usingnamespacestd;

voidprint(multimap<string,vector<string>> &family)
{
            //按照英文名称习惯打印名字,如Tom.Green
            for(auto&member : family)
            {
                        cout <<"Mumber is:"<<" "<< endl;
                        for(autoit = member.second.begin(); it != member.second.end(); ++it)
                        {
                                    cout << *it <<"."<< member.first << endl;
                        }
                        cout << endl;
            }
}
intmain()
{
            stringfname ="", name ="";
            vector<string> vec = {"Tom","Jerry","Lucy"};
            multimap<string,vector<string>> family = { {"Green", vec }, {"white", vec } };

            print(family);//打印结果

            //先输入family name,然后自己name
            //while (cin >> fname >> name)
            //family[fname].push_back(name);

            //修改地方,先输入名,再输入姓,可以重复保存了,所以不像上面那样来插入名字
            cout <<"请输入你的名:\n";
            while(cin >> fname)
            {
                        vector<string> vec;
                        cout <<"请输入你的性(输入end退出):\n";
                        while(cin >> name && name !="end")//以end结束输入
                        {
                                    vec.push_back(name);
                        }
                                    family.insert({fname,vec });//将姓插入到名前面
                                    //添加新家庭后再次打印
                                    print(family);
            }     
            return0;
}

pair类型
类似容器,pair是一个用来生成特定类型的模版。与其他标准库类型不同,pair的数据成员public的两个成员分别命名为first和second。

关联容器的操作

向map中添加元素
对于一个map进行insert操作时,必须记住元素类型是pair。

练习11.20:
重写单词计数程序,使用insert代替下标操作。你认为哪个程序更容易编写和阅读
#include<iostream>
#include<vector>
#include<map>
#include<string>
usingnamespacestd;

intmain()
{
            map<string,size_t> word_count;
            stringword;
            cout <<"请输入一串字符串\n";
            while(cin >> word)
            {
                        if(word =="#")
                                    break;
                        autoret = word_count.insert({ word, 1 });//创建一个pair
                        if(!ret.second)
                        {
                                    ++ret.first->second;//map中值部分
                        }
            }
            for(auto&w : word_count)
                        cout << w.first <<" "<< w.second << ((w.second > 1) ?" times ":" time ")<<endl;

            return0;
}

删除元素

练习11.31:
编写程序,定义一个作者及其作品的multimap。使用find在multimap中查找一个元素并用erase删除它。确保你的程序在元素不在map中时也能正常运行。
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
usingnamespacestd;

intmain()
{
            multimap<string,string> authors{ {"alan","DMA"}, {"pezy","LeetCode"}, {"alan","CLRS"},
            {"wang","FTP"}, {"pezy","CP5"}, {"wang","CPP-Concurrency"} };
            
            cout <<"erase before:\n";
            for(auto&a : authors)
                        cout << a.first <<":"<<a.second<< endl;

            stringauthor ="pezy";
            stringwork ="CP5";

            autofound = authors.find(author);//找到作者;
            autocount = authors.count(author);//记录次数;
            while(count)
            {
                        if(found->second == work)//找到CP5,然后删除;
                        {
                                    authors.erase(found);
                                    break;
                        }
                        ++found;
                        --count;
            }
            cout <<"erase after:\n";
            for(constauto& author : authors)
                        cout << author.first <<":"<< author.second << std::endl;

            return0;
}

0 0
原创粉丝点击