C ++ STL - map and multimap

table of Contents


Note: The original is not easy, reproduced, please be sure to indicate the source and author, thanks for the support!

A map and multimap

with respect to the set difference map: map having a real value and a key, automatically sorted according to the key values ​​of all the elements. pair is referred to as a first key element, the second element is referred to as a real value. map is also based on the underlying implementation mechanism for the red-black tree.

We can not map iterator to modify the keys of the map, because the key relationship related to the regular arrangement of elements within the container, any change will destroy the keys arranged in regular containers, but you can change the actual value.

Map and multimap difference is that there is not allowed the same key map, multimap allow the same key value exists.

Constructor

map<T1 T2> mp;      // 默认构造函数
map(const map &mp); // 拷贝构造函数

Assignment

map &operator-(const map &mp);  // 重载等号运算符
swap(mp);                       // 交换两个集合容器

The size of the operation

size();     // 返回容器中元素的数目
empty();    // 判断容器是否为空

Inserting the data element operations

map<int, string> mp;

// 第一种,通过pair的方式插入对象
mp.insert(pair<int, string>(3, "小张"));

// 第二种,通过pair的方式插入对象
mp.insert(make_pair(-1, "小张"));

// 第三种,通过value_type的方式插入对象
mp.insert(map<int, string>::value_type(1, "小李"));

// 第四重,通过数组的方式插入
mp[3] = "小刘";
mp[5] = "小王";

(1) in front of the three methods, using the insert () method returns the value pair <iterator, bool>

(2) The fourth method is straightforward, but there is a problem of performance. 3 is inserted, the first look mp primary key for the item 3, if not found, then a key is 3, the value of the initial value of the group inserted into mp, then the value changed to "Liu." If it is found that 3 key already exists, then modify the key corresponding to the value.

(3) string strName = mp [2]; 2 only when the key is the correct value mp present operation, NO is automatically inserted in one example, key 2, the value is initialized.

Deletion

clear();            // 删除所有元素
erase(pos);         // 删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg, end);    // 删除区间[beg, end)的所有元素,返回下一个元素的迭代器
erase(keyElem);     // 删除容器中key为keyElem的对组

Find operation

find(key);              // 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回mp.end()
count(keyElem);         // 返回容器中key为keyElem的对组个数。对map来说,要么是0,要么是1。对于multimap来说,值可能大于1
lower_bound(keyElem);   // 返回第一个key <= keyElem元素的迭代器
upper_bound(keyElem);   // 返回第一个key > keyElem元素的迭代器
equal_range(keyElem);   // 返回容器中key与keyElem相等的上下限的两个迭代器

This is a map of the application case.

// 初始化和插入数据
void Test1()
{
    // 第一个为key的类型,第二个为value的类型
    map<int, string> mp;

    // 插入数据
    typedef pair<int, string> itemType;

    itemType i1;
    i1.first = 1;
    i1.second = "ZHAO";
    mp.insert(i1);

    // 判断是否插入成功
    pair<map<int, string>::iterator, bool> r1 = mp.insert(itemType(2, "QIAN"));
    if (r1.second)
    {
        cout << "插入成功!" << endl;
    }
    else
    {
        cout << "插入失败!" << endl;
    }

    // key如果相等,则插入失败
    pair<map<int, string>::iterator, bool> r2 = mp.insert(itemType(2, "KKK"));
    if (r2.second)
    {
        cout << "插入成功!" << endl;
    }
    else
    {
        cout << "插入失败!" << endl;
    }

    mp.insert(make_pair(3, "SUN"));
    mp.insert(map<int, string>::value_type(4, "LI"));

    // 与使用insert()不同的时,使用数组的方式,即使插入相同的key值元素
    // 也不会报插入失败的错误。而是会把key对应的value值给更新成新的value值
    mp[5] = "ZHOU";
    mp[5] = "WU";
    // 总结:使用数组的插入方式。如果key不存在,则插入新的键值对;如果key存在,则将旧的value修改成新的value

    // 注意:map存储的是pair
    decltype(mp.begin()) it;
    for (it = mp.begin(); it != mp.end(); ++it)
    {
        cout << it->first << " : " << it->second << endl << endl;
    }

    // 如果尝试打印不存在的key,则value会输出value类型的默认值
    // 对于string类型,其默认值为空字符串,所以value输出值为空
    // 并且新的键值对“-1 : 空”会被插入到map中!!!
    cout << "mp[-1] = " << mp[-1] << endl;

    for (it = mp.begin(); it != mp.end(); ++it)
    {
        cout << it->first << " : " << it->second << endl;
    }

}

Here is a comprehensive application case of a multimap.

#define SALE_DEPARTMENT 1
#define DEVELOP_DEPARTMENT 2
#define FINACIAL_DEPARTMENT 3

class Worker
{
public:
    string mName;
    string mTel;
    int mAge;
    int mSalary;
};

void CreateWorker(vector<Worker> &worker)
{
    string seedName = "ABCDE";
    for (int i = 0; i < 5; ++i)
    {
        Worker w;
        w.mName = "员工";
        w.mName += seedName[i];
        w.mAge = 20 + rand() % 10;
        w.mTel = "010-88888888";
        w.mSalary = rand() % 1000 + 10000;

        worker.push_back(w);
    }
}

void WorkerByGroup(vector<Worker> &worker, multimap<int, Worker> &workerGroup)
{
    // 随机分配到不同部门
    for (vector<Worker>::iterator it = worker.begin(); it != worker.end(); ++it)
    {
        int departID = rand() % 3 + 1;
        switch (departID)
        {
        case SALE_DEPARTMENT:
            workerGroup.insert(make_pair(SALE_DEPARTMENT, *it));
            break;
        case DEVELOP_DEPARTMENT:
            workerGroup.insert(make_pair(DEVELOP_DEPARTMENT, *it));
            break;
        case FINACIAL_DEPARTMENT:
            workerGroup.insert(make_pair(FINACIAL_DEPARTMENT, *it));
            break;
        default:
            break;
        }
    }
}

void PrintWorkerByGroup(multimap<int, Worker> &workerGroup)
{
    // 打印所有员工信息
    cout << "所有员工信息:" << endl;
    multimap<int, Worker>::iterator it;
    for (it = workerGroup.begin(); it != workerGroup.end(); ++it)
    {
        cout << "Name = " << it->second.mName << endl;
        cout << "Age = " << it->second.mAge << endl;
        cout << "Tel = " << it->second.mTel << endl;
        cout << "Salary = " << it->second.mSalary << endl;
        switch (it->first)
        {
        case SALE_DEPARTMENT:
            cout << "Department = SALE_DEPARTMENT" << endl;
            break;
        case DEVELOP_DEPARTMENT:
            cout << "Department = DEVELOP_DEPARTMENT" << endl;
            break;
        case FINACIAL_DEPARTMENT:
            cout << "Department = FINACIAL_DEPARTMENT" << endl;
            break;
        default:
            break;
        }
        cout << endl;
    }

    // 打印销售部门信息
    cout << "销售部门信息:" << endl;
    multimap<int, Worker>::iterator ret = workerGroup.find(SALE_DEPARTMENT);
    int departCount = workerGroup.count(SALE_DEPARTMENT);
    int num = 0;
    for (it = ret; it != workerGroup.end() && num < departCount; ++it, ++num)
    {
        cout << (it->second).mName << endl;
    }
}

map and set as when you use the map to store custom type requires that the simulation function to specify the type of custom collation.

class MyKey
{
public:
    MyKey(int index, int id) : mIndex(index), mID(id) {}
public:
    int mIndex;
    int mID;
};

class mycmp
{
public:
    bool operator()(const MyKey &k1, const MyKey &k2)
    {
        return k1.mIndex > k2.mIndex;
    }
};
int main(int argc, char **argv)
{
    // 以下的写法无法通过编译
    // map<MyKey, int> mp;
    // mp.insert(make_pair(MyKey(1, 2), 10));
    // mp.insert(make_pair(MyKey(4, 5), 20));

    map<MyKey, int, mycmp> mp;
    mp.insert(make_pair(MyKey(1, 2), 10));
    mp.insert(make_pair(MyKey(4, 5), 20));
    for (map<MyKey, int, mycmp>::iterator it = mp.begin(); it != mp.end(); ++it)
    {
        cout << "Index = " << it->first.mIndex << endl;
        cout << "ID = " << it->first.mID << endl;
        cout << "second = " << it->second << endl;
        cout << endl;
    }


    getchar();
    return 0;
}

Guess you like

Origin www.cnblogs.com/laizhenghong2012/p/11785877.html