美文网首页
STL(二)map/multimap

STL(二)map/multimap

作者: 第八区 | 来源:发表于2017-08-30 15:04 被阅读68次

    map

    Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力。由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。

    • 增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。
    • 对于迭代器来说,可以修改实值,而不能修改key
    • 自动建立Key - value的对应。key 和 value可以是任意你需要的类型。

    插入

    • pair
    • value_type
    • []

    pair 和value_type正常插入,如果key相同则插入失败。insert返回pair<iterator,bool>,可判断插入结果。而[]是修改元素,如果key不存在则插入,如果存在则覆盖。

    删除

    erase

    • 根据key删除
    • 使用迭代器删除,遵循前闭后开原则

    查找

    find,返回iterator。查找成功则返回对应元素的迭代器,查找失败则等于end()

    #include "stdafx.h"
    #include "iostream"
    using namespace std;
    #include "map"
    //遍历打印map
    void print(map<int, string> & m) {
        for (map<int, string>::iterator it = m.begin(); it != m.end(); it++) {
            cout << it->first << " " << it->second.c_str() << endl;
        }
    }
    //打印insert返回结果
    void printInsertResPair(pair<map<int, string>::iterator, bool>& p) {
        cout << "插入结果 " << p.second << " |" << p.first->first<<" "<<p.first->second.c_str() << endl;
    }
    //打印find返回结果
    void printFindResIt(map<int,string>&m,map<int, string>::iterator& it) {
        if (it != m.end()) {
            cout << "查找成功 " << it->first << " " << it->second.c_str() << endl;
        }
        else {
            cout << "查找失败" << endl;
        }
    }
    int main()
    {
        map<int, string> nameMap;
        cout << "-------insert(pair)方式插入-------" << endl;
        nameMap.insert(pair<int, string>(1, "a"));
        nameMap.insert(pair<int, string>(3, "c"));
        nameMap.insert(pair<int, string>(2, "b"));
        print(nameMap);
        cout << "-------insert(value_type)方式插入-------" << endl;
        pair<map<int, string>::iterator, bool> p;
        nameMap.insert(map<int, string>::value_type(4, "d"));
        p = nameMap.insert(map<int, string>::value_type(5, "e"));
        printInsertResPair(p);
        p = nameMap.insert(map<int, string>::value_type(5, "f"));
        printInsertResPair(p);
        print(nameMap);
        cout << "-------[]方式插入-------" << endl;
        nameMap[5] = "g";
        nameMap[6] = "h";
        nameMap[7] = "i";
        print(nameMap);
        cout << "-------查找-------" << endl;
        map<int, string>::iterator it;
        it=nameMap.find(5);
        printFindResIt(nameMap,it);
        it = nameMap.find(10);
        printFindResIt(nameMap, it);
        cout << "-------key删除-------" << endl;
        nameMap.erase(1);
        print(nameMap);
        cout << "-------迭代器删除(前闭后开)-------" << endl;
        it = nameMap.find(4);
        nameMap.erase(nameMap.begin(),it);
        print(nameMap);
        return 0;
    }
    
    案例1.png

    multimap

    标准库还定义了一个 multimap 容器,它与 map 类似,所不同的是它允许重复键。这个属性使得 multimap 比预想的要更有用:比如在电话簿中相同的人可以有两个以上电话号码,文件系统中可以将多个符号链接映射到相同的物理文件,或DNS服务器可以将几个URLs映射到相同的IP地址。

    插入

    multimap::insert()成员函数返回指向新插入元素的迭代指针,也就是 iterator(multimap::insert()总是能执行成功)。但是 map::insert() 返回 pair<iterator, bool>,此处 bool 值表示插入操作是否成功。

    查找

    • find(k) 返回匹配的第一个元素的迭代器。如果需要获取所有匹配元素,则需要遍历再次判断。

      it = m.find("it");
      while (it!=m.end())
      {
        if (it->first == "it") {
          cout << it->first << " ";
          it->second.print();
          it++;
        }
        else {
          break;
        }
      }
      

    • equal_range(k) 该函数查找所有与 k 关联的值。返回迭代指针的 pair,它标记开始和结束范围。

      pair<multimap<string,Student>::iterator, multimap<string,Student>::iterator> pEqual=m.equal_range("it");
      for (multimap<string, Student>::iterator it = pEqual.first; it != pEqual.second;it++) {
        cout << it->first << " ";
        it->second.print();
      }
      

    虽然 map 和 multimap 具有相同的接口,其重要差别在于重复键,设计和使用要区别对待。此外,还要注意每个容器里 insert()成员函数的细微差别。

    #include "stdafx.h"
    #include "iostream"
    #include "string"
    #include "map"
    using namespace std;
    
    class Student {
    private:
        string name;
        int number;
    public:
        Student(int number, string name) {
            cout << "构造" << number << endl;
            this->number = number;
            this->name = name;
        }
        Student(const Student& student) {
            cout << "拷贝构造" << student.getNumber()<<" "<<student.getName().c_str() << endl;
            this->number = student.getNumber();
            this->name = student.getName();
        }
    
        void print()const {
            cout << this->number << " " << this->name << endl;
        }
    
        string getName()const {
            return this->name;
        }
    
        int getNumber()const {
            return this->number;
        }
    };
    
    void print(multimap<string, Student>& map) {
        for (multimap<string, Student>::iterator it=map.begin(); it != map.end(); it++) {
            cout << it->first.c_str() << " ";
            it->second.print();
        }
    }
    int main()
    {
        multimap<string, Student> m;
        Student stu1(1, "a");
        cout << "--------------" << endl;
        //Student会执行拷贝构造
        pair<string, Student> p = pair<string, Student>("it", stu1);
        cout << "--------------" << endl;
        //Student会再一次执行拷贝构造
        m.insert(p);
        cout << "--------------" << endl;
        m.insert(pair<string, Student>("it", Student(2, "b")));
        m.insert(pair<string, Student>("sale", Student(3, "c")));
        m.insert(pair<string, Student>("product", Student(4, "d")));
        cout << "-------遍历插入结果-------" << endl;
        print(m);
        int count=m.count("it");
        cout << "cout(\"it\")=" << count << endl;
        multimap<string, Student>::iterator it;
        cout << "-------find(\"it\")查找单个值-------" << endl;
        it = m.find("it");
        while (it!=m.end())
        {
            if (it->first == "it") {
                cout << it->first << " ";
                it->second.print();
                it++;
            }
            else {
                break;
            }
        }
        cout << "-------equal_range处理多个关联值-------" << endl;
        pair<multimap<string,Student>::iterator, multimap<string,Student>::iterator> pEqual=m.equal_range("it");
        for (multimap<string, Student>::iterator it = pEqual.first; it != pEqual.second;it++) {
            cout << it->first << " ";
            it->second.print();
        }
        cout << "-------size-------" << endl;
        cout << m.size() << endl;
        return 0;
    }
    
    案例2.png

    相关文章

      网友评论

          本文标题:STL(二)map/multimap

          本文链接:https://www.haomeiwen.com/subject/qxitjxtx.html