首页 > 代码库 > 【足迹C++primer】38、关联容器操作(1)

【足迹C++primer】38、关联容器操作(1)

关联容器操作

关联容器中还定义了三个类型,如下:
    set<string>::value_type v1;     //这个v1是string类型
    set<string>::key_type v2;       //这个v2是string类型
    map<string, int>::value_type v3;    //v3是pair类型pair<const string, int>
    map<string, int>::key_type v4;      //v4是string类型
    map<string, int>::mapped_type v5;   //v5是int类型

关联容器迭代器

对map而言,value_type是一个pair类型的!!!
我已经感受到了这章有点多,所以分成两部分了- -
    map<string, size_t> word_count; // empty map from string to size_t
    string word;
    while (cin >> word)
      ++word_count[word];

    //获得指向word_count中的一个元素的迭代器
    auto map_it=word_count.begin();
    //*map_it是指向一个pair<const string, size_t>对象的引用
    cout<<map_it->first;        //打印此元素的关键字
    cout<<" "<<map_it->second;  //打印此元素的值
//    map_it->first="new key";    //错误:关键字是const的
    ++map_it->second;           //正确:我们可以通过迭代器改变元素

set的迭代器是const的

这就是说,这个set的值是没法更改的!

//可以用一个set迭代器来读取元素的值,但不能修改
void fun3()
{
    set<int> iset={0,1,2,3,4,5,6,7,8,9};
    set<int>::iterator set_it=iset.begin();
    if(set_it != iset.end())
    {
//        *set_it=42;     //错误!!!
        cout<<*set_it<<endl;    //正确:可以读关键字
    }
}

遍历关联容器

//遍历关联容器
void fun4()
{
    map<string, size_t> word_count; // empty map from string to size_t
    string word;
    while (cin >> word)
      ++word_count[word];

    //获得指向word_count中的一个元素的迭代器
    auto map_it=word_count.cbegin();
    //比较当前迭代器和尾后迭代器
    while(map_it != word_count.cend())
    {
        //解引用迭代器,打印关键字-值对
        cout<<map_it->first<<" occurs "
            <<map_it->second<<" times "<<endl;

        ++map_it;   //递增迭代器,移动到下一个元素
    }
}

添加元素

    vector<int> ivec={2,4,6,8,2,4,6,8};     //ivec有8个元素
    set<int> set2;          //空集合
    set2.insert(ivec.cbegin(), ivec.cend());    //set2有4个元素
    set2.insert({1,3,5,7,1,3,5,7});         //现在set2有8个元素

关联容器的insert成员向容器中添加一个元素或一个元素范围。
好蛋疼啊!!!这都放假了,我还在敲代码。
//向map添加元素
void fun6()
{
    map<string, size_t> word_count; // empty map from string to size_t
    string word;
    while (cin >> word)
      ++word_count[word];

    //向word_count插入word的4种方法
    word_count.insert({word, 1});
    word_count.insert(make_pair(word, 1));
    word_count.insert(pair<string, size_t>(word, 1));
    word_count.insert(map<string, size_t>::value_type(word, 1));
}

检测insert的返回值

pair的first成员是一个迭代器,指向具有给定关键字的元素;second成员是一个bool值,指出元素是插入成功还是已经存放在于容器中。
现在的感觉可就是我要速度吧这本书搞完!!!!
//检查insert的返回值
//重写单词计数程序
void fun7()
{
    map<string, size_t> word_count; //从string到size_t的空map
    string word;
    while(cin>>word)
    {
        //插入一个元素,关键字等于word,值为1
        //若word已在word_count中,insert什么也不做
        auto ret=word_count.insert({word, 1});
        if(!ret.second)
        {
            ++ret.first->second;    //递增计数器
        }
    }
}

向multimap和multiset添加元素,这个可以重复

这就一句话,看标题,如果不懂什么叫multimap和multiset点击超链接
//向multimap和multiset添加元素,这个可以重复
void fun8()
{
    multimap<string, string> authors;
    //插入第一个元素,关键字为Barth, John
    authors.insert({"Barth, John", "Sot-Weed Factor"});
    //正确:添加第二个元素,关键字也是Barth, John
    authors.insert({"Barth, John", "Lost in the Funhouse"});
}

删除元素

关联容器定义了三个版本的erase
c.erase(k) 把k给我删除了,返回一个size_type值,指出删除的元素的数量
c.erase(p) 吧p指向的元素删掉,p是一个迭代器p不能指向c.end()
c.erase(b, e) 删除迭代器对b和e所表示的范围中的元素。返回e

//删除元素
void fun9()
{
    map<string, size_t> word_count; // empty map from string to size_t
    string word,removal_word;
    while (cin >> word)
      ++word_count[word];

    //删除一个关键字,返回删除的元素数量
    cin>>removal_word;
    if(word_count.erase(removal_word))
        cout<<" ok: "<<removal_word<<" remove\n";
    else
        cout<<" oops: "<<removal_word<<" not found!\n";
}

完整全部代码:

/**
* 功能:关联容器操作
* 时间:2014年6月26日16:40:51
* 作者:cutter_point
*/

#include<iostream>
#include<set>
#include<map>
#include<vector>
#include<string>

using namespace std;

//关联容器额外的类型别名
void fun1()
{
    set<string>::value_type v1;     //这个v1是string类型
    set<string>::key_type v2;       //这个v2是string类型
    map<string, int>::value_type v3;    //v3是pair类型pair<const string, int>
    map<string, int>::key_type v4;      //v4是string类型
    map<string, int>::mapped_type v5;   //v5是int类型
}

//关联容器迭代器
void fun2()
{
    map<string, size_t> word_count; // empty map from string to size_t
    string word;
    while (cin >> word)
      ++word_count[word];

    //获得指向word_count中的一个元素的迭代器
    auto map_it=word_count.begin();
    //*map_it是指向一个pair<const string, size_t>对象的引用
    cout<<map_it->first;        //打印此元素的关键字
    cout<<" "<<map_it->second;  //打印此元素的值
//    map_it->first="new key";    //错误:关键字是const的
    ++map_it->second;           //正确:我们可以通过迭代器改变元素
}

//可以用一个set迭代器来读取元素的值,但不能修改
void fun3()
{
    set<int> iset={0,1,2,3,4,5,6,7,8,9};
    set<int>::iterator set_it=iset.begin();
    if(set_it != iset.end())
    {
//        *set_it=42;     //错误!!!
        cout<<*set_it<<endl;    //正确:可以读关键字
    }
}

//遍历关联容器
void fun4()
{
    map<string, size_t> word_count; // empty map from string to size_t
    string word;
    while (cin >> word)
      ++word_count[word];

    //获得指向word_count中的一个元素的迭代器
    auto map_it=word_count.cbegin();
    //比较当前迭代器和尾后迭代器
    while(map_it != word_count.cend())
    {
        //解引用迭代器,打印关键字-值对
        cout<<map_it->first<<" occurs "
            <<map_it->second<<" times "<<endl;

        ++map_it;   //递增迭代器,移动到下一个元素
    }
}

//添加元素
void fun5()
{
    vector<int> ivec={2,4,6,8,2,4,6,8};     //ivec有8个元素
    set<int> set2;          //空集合
    set2.insert(ivec.cbegin(), ivec.cend());    //set2有4个元素
    set2.insert({1,3,5,7,1,3,5,7});         //现在set2有8个元素
}

//向map添加元素
void fun6()
{
    map<string, size_t> word_count; // empty map from string to size_t
    string word;
    while (cin >> word)
      ++word_count[word];

    //向word_count插入word的4种方法
    word_count.insert({word, 1});
    word_count.insert(make_pair(word, 1));
    word_count.insert(pair<string, size_t>(word, 1));
    word_count.insert(map<string, size_t>::value_type(word, 1));
}

//检查insert的返回值
//重写单词计数程序
void fun7()
{
    map<string, size_t> word_count; //从string到size_t的空map
    string word;
    while(cin>>word)
    {
        //插入一个元素,关键字等于word,值为1
        //若word已在word_count中,insert什么也不做
        auto ret=word_count.insert({word, 1});
        if(!ret.second)
        {
            ++ret.first->second;    //递增计数器
        }
    }
}


//向multimap和multiset添加元素,这个可以重复
void fun8()
{
    multimap<string, string> authors;
    //插入第一个元素,关键字为Barth, John
    authors.insert({"Barth, John", "Sot-Weed Factor"});
    //正确:添加第二个元素,关键字也是Barth, John
    authors.insert({"Barth, John", "Lost in the Funhouse"});
}

//删除元素
void fun9()
{
    map<string, size_t> word_count; // empty map from string to size_t
    string word,removal_word;
    while (cin >> word)
      ++word_count[word];

    //删除一个关键字,返回删除的元素数量
    cin>>removal_word;
    if(word_count.erase(removal_word))
        cout<<" ok: "<<removal_word<<" remove\n";
    else
        cout<<" oops: "<<removal_word<<" not found!\n";
}

int main()
{
    fun1();
    fun2();
    fun3();
    fun4();
    fun5();
    fun6();
    fun7();
    fun8();
    fun9();
    return 0;
}




PS:最后可能要说的就是,放假的这段时间微博可能会停更了,应为暑假有事情要做,而且不像在学校那么闲,估计会停更2个月,但是学习我是不会停的,哈哈,到时微博更新的时候没准已经不是C++primer的内容了,大家也要加油啊!!!!到时候可不要被我超出去了哦大笑