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

一 map和multimap

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

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

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

构造函数

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

赋值操作

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

大小操作

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

插入数据元素操作

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)前面三种方法,采用的是insert()方法,该方法的返回值为pair<iterator, bool>

(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<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;
} }

下面是一个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和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<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;
}

C++ STL——map和multimap的更多相关文章

  1. STL Map和multimap 容器

    STL Map和multimap 容器 map/multimap的简介 map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供 基于key的快速检索能力.       ...

  2. [STL] map,multimap,unordered_map基本用法

    map的特性是,所有元素都会根据元素的键值自动被排序.map的所有元素都是pair,同时拥有键值(key)和实值(value).pair的第一元素被视为键值,第二元素被视为实值.map不允许两个元素拥 ...

  3. STL(六)——map、multimap

    STL--map.multimap 文章目录 STL--map.multimap 关联容器与map的介绍 map与set的异同 map与multimap的异同 map类对象的构造 map添加元素 ma ...

  4. STL的基本使用之关联容器:map和multiMap的基本使用

    STL的基本使用之关联容器:map和multiMap的基本使用 简介 map 和 multimap 内部也都是使用红黑树来实现,他们存储的是键值对,并且会自动将元素的key进行排序.两者不同在于map ...

  5. 【C++ STL】Map和Multimap

    1.结构 Map和multimap将key/value pair(键值/实值 队组)当作元素,进行管理.他们根据key的排序准则将元素排序.multimap允许重复元素,map不允许. 元素要求: k ...

  6. STL之Map和multimap容器

    1.Map和multimap容器 1)map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. 2)map中key值是唯一的.集合中的元素按一 ...

  7. C++ STL 学习笔记__(8)map和multimap容器

    10.2.9 Map和multimap容器 map/multimap的简介 ²  map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. ² ...

  8. STL标准库-容器-map和multimap

    技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 map与multimap为关联容器,结构如下 map底层实现依然是rb_tree 他的data可以改,但是key不能改,因此ma ...

  9. STL中 map 和 multimap

    1. 所在头文件<map>. 命名空间std, 声明如下: namespace std{ template <class Key,class T, class Compare = l ...

随机推荐

  1. iphone SprintBoard部分私有API总结(不支持iOS8)

    本文介绍iOS SrpintBoard框架的部分私有API,具体包括: 获取ios上当前正在运行的所有App的bundle id(不管当前程序是在前台还是后台都可以) 获取ios上当前前台运行的App ...

  2. Redis和MemCache静态Map做缓存区别

    本地缓存和分布式缓存 本地缓存:使用自带的map或者guava实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着jvm的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不 ...

  3. 【Git】二、文件的提交与查看

    提要 //添加git跟踪文件,stage操作 $git add readme.txt //提交到本地分支 $git commit -m xxx //查看当前git工作状态,可以看到未跟踪文件,已跟踪未 ...

  4. Delphi 类的方法

  5. troubshooting-sqoop 导出 TiDB表数据报com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

    2019-11-22 17:15:27,705 FATAL [IPC Server handler 13 on 44844] org.apache.hadoop.mapred.TaskAttemptL ...

  6. python再学习笔记

    python各种半桶水QAQ,一些特性经常跟其他语言搞混,官方入门文档重读温习...... 最好用4个空格的缩进空值是Python里一个特殊的值,用None表示变量就是在程序中用来指向这些数据对象的, ...

  7. LoadRunner(3)

    一.性能测试的策略 重要的:基准测试.并发测试.在线综合场景测试 递增测试.极限测试... 1.基准测试:Benchmark Testing 含义:就是单用户测试,单用户.单测试点.执行n次: 作为后 ...

  8. Codeforces 1148 E - Earth Wind and Fire

    E - Earth Wind and Fire 思路: 栈模拟 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC opti ...

  9. 如何避免重复安装AppiumSetting、Unlock以及Android ime

    老版本Appium(如1.4.16),找到如下路径(根据自己的安装路径找) C:\Program Files (x86)\Appium\node_modules\appium\lib\devices\ ...

  10. 表单重置时 <input type=“hidden”> 隐藏域不可被重置

    可封装全局样式 .hide{ display:none; } 用 <input type="text" class="hide"/> 替代