map multimapc++_C++ STL——map和multimap

[TOC]

注:原创不易,转载请务必注明原作者和出处,感谢支持!

一 map和multimap

map相对于set的区别:map具有键值和实值,所有元素根据键值自动排序。pair的第一元素被称为键值,第二元素被称为实值。map也是以红黑树为底层实现机制。

我们不能通过map的迭代器来修改map的键值,因为键值关系关系到容器内元素的排列规则,任意改变键值会破坏容器的排列规则,但是你可以改变实值。

map和multimap的区别在于,map不允许相同key值存在,multimap则允许相同的key值存在。

构造函数

map mp;// 默认构造函数

map(const map &mp);// 拷贝构造函数

赋值操作

map &operator-(const map &mp);// 重载等号运算符

swap(mp);// 交换两个集合容器

大小操作

size();// 返回容器中元素的数目

empty();// 判断容器是否为空

插入数据元素操作

map mp;

// 第一种,通过pair的方式插入对象

mp.insert(pair(3, "小张"));

// 第二种,通过pair的方式插入对象

mp.insert(make_pair(-1, "小张"));

// 第三种,通过value_type的方式插入对象

mp.insert(map::value_type(1, "小李"));

// 第四重,通过数组的方式插入

mp[3] = "小刘";

mp[5] = "小王";

(1)前面三种方法,采用的是insert()方法,该方法的返回值为pair

(2)第四种方法非常直观,但存在一个性能的问题。插入3时,先在mp中查找主键为3的项,若没有发现,则将一个键为3,值为初始化值的对组插入到mp中,然后再将值修改为"小刘"。若发现已存在3这个键,则修改这个键对应的value。

(3)string strName = mp[2];只有当mp存在2这个键时才是正确的取值操作,否在会自动插入一个实例,键为2,值为初始化值。

删除操作

clear();// 删除所有元素

erase(pos);// 删除pos迭代器所指的元素,返回下一个元素的迭代器

erase(beg, end);// 删除区间[beg, end)的所有元素,返回下一个元素的迭代器

erase(keyElem);// 删除容器中key为keyElem的对组

查找操作

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相等的上下限的两个迭代器

这是map的应用案例。

// 初始化和插入数据

void Test1()

{

// 第一个为key的类型,第二个为value的类型

map mp;

// 插入数据

typedef pair itemType;

itemType i1;

i1.first = 1;

i1.second = "ZHAO";

mp.insert(i1);

// 判断是否插入成功

pair::iterator, bool> r1 = mp.insert(itemType(2, "QIAN"));

if (r1.second)

{

cout << "插入成功!" << endl;

}

else

{

cout << "插入失败!" << endl;

}

// key如果相等,则插入失败

pair::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::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;

}

}

下面是一个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)

{

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, multimap &workerGroup)

{

// 随机分配到不同部门

for (vector::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 &workerGroup)

{

// 打印所有员工信息

cout << "所有员工信息:" << endl;

multimap::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::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和set一样,当你使用map来存储自定义类型时,需要使用仿函数来指定自定义类型的排序规则。

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 mp;

// mp.insert(make_pair(MyKey(1, 2), 10));

// mp.insert(make_pair(MyKey(4, 5), 20));

map mp;

mp.insert(make_pair(MyKey(1, 2), 10));

mp.insert(make_pair(MyKey(4, 5), 20));

for (map::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;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值