Map的插入操作和按照value排序
来源:互联网 发布:如何开一个淘宝网店 编辑:程序博客网 时间:2024/05/17 06:21
背景
对比map的插入操作说明和按照value排序,根据value值的查找。
说明
常见的map插入操作有两种,一种是通过操作符[]进行插入,另一种则是通过insert成员函数进行插入。
[]操作符进行插入。
[]操作符
示例:
std::map<int,string> map1;map1[2]="Hello";
插入2时,先在map1中查找主键为2的项,没发现,然后将一个新的对象插入map1中,键是2,此时的值是一个空字符串,在插入完成后,将字符串赋为”Hello”。 该方法会将每个值都赋为缺省值,然后再赋为需要显示的值,如果元素是类对象,则开销比较大。[]操作,时间复杂度为logn,n为map的容量。
用insert方法可以避免上述开销。
此外需要注意的是,用下标访问map中不存在的元素时,将导致向map中添加该下标所指向的新元素,其值会根据类型默认值或默认构造函数进行初始化(如int或初始化为0,string初始化为“”)。
insert操作
insert的时候会检查是否key冲突,不冲突才进行insert操作,否则该insert操作会被忽略。可以用pair来验证是否插入成功。通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。
插入value_type数据
std::map<int, string> mapStudent;mapStudent.insert(map<int, string>::value_type (1, “student_one”));mapStudent.insert(map<int, string>::value_type (2, “student_two”));std::pair<std::map<int,string>::iterator,bool> ret;ret = mapStudent.insert ( std::pair<int,string>(2,"X man") );if (ret.second==false) { std::cout << "element '2' already existed"; std::cout << " with a value of " << ret.first->second << '\n';}
插入pair数据
std::map<int,string> mapStudent;std::map<int,string>::iterator it =mapStudent.begin();mapStudent.insert (it, std::pair<int,string>(2,"student_2")); // max efficiency insertingmapStudent.insert (it, std::pair<int,string>(3,"student_3")); // no max efficiency inserting
范围插入
用法void insert (InputIterator first, InputIterator last),以其他map的迭代器作为入参,将该范围内的数据插入到该map中,包括临界值。
// third insert function version (range insertion):std::map<int,string> anothermap;anothermap.insert(mapStudent.begin(),mapStudent.find(2));
综合,代码如下:
// first insert function version (single parameter): std::map<int, string> mapStudent; mapStudent.insert(map<int, string>::value_type (1, "student_1")); mapStudent.insert(map<int, string>::value_type (7, "student_7")); std::pair<std::map<int,string>::iterator,bool> ret; ret = mapStudent.insert ( std::pair<int,string>(7,"X man") ); if (ret.second==false) { std::cout << "element '2' already existed"; std::cout << " with a value of " << ret.first->second << '\n'; } // second insert function version (with hint position): std::map<int,string>::iterator it = mapStudent.begin(); mapStudent.insert (it, std::pair<int,string>(2,"student_2")); // max efficiency inserting mapStudent.insert (it, std::pair<int,string>(3,"student_3")); // no max efficiency inserting // third insert function version (range insertion): std::map<int,string> anothermap; anothermap.insert(mapStudent.begin(),mapStudent.find(3)); // showing contents: std::cout << "mapStudent contains:\n"; for (it=mapStudent.begin(); it!=mapStudent.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; std::cout << "anothermap contains:\n"; for (it=anothermap.begin(); it!=anothermap.end(); ++it) std::cout << it->first << " => " << it->second << '\n';
展示如下:
map排序
map内部是根据键进行排序的,如果想要修改其排序对象呢,按照value进行排序呢?
如果想要采用sort函数,该怎么办?sort函数有个限制,利用sort函数只能对序列容器进行排序,就是线性的(如vector,list,deque)。map也是一个集合容器,它里面存储的元素是pair,但是它不是线性存储的,所以利用sort不能直接和map结合进行排序。如果把map中的元素放到序列容器(如vector)中,然后再对这些元素进行排序呢?要对序列容器中的元素进行排序,也有个必要条件:就是容器中的元素必须是可比较的,也就是实现了<操作的。将map的元素以PAIR放置与vector中,再用sort函数,对其排序,其中需要指定排序方法。这里有两种方式, 比较函数和函数对象的方式。因为我们知道sort的定义如下:
template <class RandomAccessIterator> void sort ( RandomAccessIterator first, RandomAccessIterator last ); template <class RandomAccessIterator, class Compare> void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );
在使用过程中,我们需要自定义Compare。sort函数是在调用时指定的,可以传入函数指针或者函数对象。当传入一个对象,类名()就会调用构造函数生成对象,当传入一个函数指针,就是把上面说的第一种方法的函数名传过来。(注意,函数对象和函数指针的区别。但是,在程序代码中,它的调用方式与函数指针一样,后面加个括号就可以了,可以细看下面的程序。)
#include<iostream>#include<map>#include<vector>#include<string>#include<algorithm>using namespace std;typedef pair<string, int> PAIR;//实现对pair按value进行比较方法1:比较函数函数的方式bool cmp_by_value(const PAIR& lhs, const PAIR& rhs) { return lhs.second < rhs.second; }//实现对pair按value进行比较方法2:函数对象的方式struct CmpByValue { bool operator()(const PAIR& lhs, const PAIR& rhs) { return lhs.second < rhs.second; } }; int main(){ map<string, int> name_score_map; name_score_map["LiMin"] = 90; name_score_map["ZiLinMi"] = 79; name_score_map["BoB"] = 92; name_score_map.insert(make_pair("Bing",99)); name_score_map.insert(make_pair("Albert",86)); //把map中元素转存到vector中 vector<PAIR> name_score_vec(name_score_map.begin(), name_score_map.end()); // sort(name_score_vec.begin(), name_score_vec.end(), CmpByValue());//指定函数对象的方式,注意这里CmpByValue(),有个括号! sort(name_score_vec.begin(), name_score_vec.end(), cmp_by_value); //指定比较函数的方式 for (int i = 0; i != name_score_vec.size(); ++i) { cout << name_score_vec[i].first<<"\t"<< name_score_vec[i].second<< endl; } return 0;}
结果如下:
两次排序分别对应函数指针和函数对象的方式。
map中根据value值的查找
map中,默认的排序是按照key值排的,map自带的find方法也是按着key值查找的。如果想要实现在map中按照value值的查找需要做
find_if的原型:
template <class InputIterator, class Predicate> InputIterator find_if(InputIterator first, InputIterator last,Predicate pred) { while (first != last && !pred(*first)) ++first; return first; }
find_if是一个模板函数,接受两个数据类型:InputItearator迭代器,Predicate用于比较数值的函数或者函数对象(仿函数)。find_if对迭代器要求很低,只需要它支持自增操作即可。当前遍历到的记录符合条件与否,判断标准就是使得pred()为真。注意观察第三个参数pred。
代码:
#include <string>#include <algorithm>class map_value_finder{public: map_value_finder(const std::string &cmp_string):m_s_cmp_string(cmp_string){} bool operator ()(const std::map<int, std::string>::value_type &pair) { return pair.second == m_s_cmp_string; }private: const std::string &m_s_cmp_string; };int main(){ std::map<int, std::string> my_map; my_map.insert(std::make_pair(10, "china")); my_map.insert(std::make_pair(20, "english")); my_map.insert(std::make_pair(30, "english")); my_map.insert(std::make_pair(40, "hongkong")); std::map<int, std::string>::iterator it = my_map.end(); it = std::find_if(my_map.begin(), my_map.end(), map_value_finder("English")); if (it == my_map.end()) printf("not found\n"); else printf("found key:%d value:%s\n", it->first, it->second.c_str()); return 0; }
class map_finder即用于比较的函数对象,它的核心就是重载的()运算符。因为每个容器迭代器的*运算符得到的结果都是该容器的value_type值,所以该运算符的形参就是map迭代器指向的value_type类型的引用。
- Map的插入操作和按照value排序
- Map的插入操作和按照value排序
- [整理]关于map的简单操作和按照Key与value的排序
- Map按照Key排序和Map按照Value排序
- map 按照value排序
- Map分别按照Key和value排序
- Map按照key和value进行排序
- java按照map的value排序
- java按照map的value排序
- java按照map的value排序
- java按照map的value排序
- java按照map的value排序
- map的排序(按照key值和按照value值)
- Map按照Value值排序
- Java Map按照Value 排序
- java map按照value排序
- Java Map集合按照key和value排序之法
- Map中按照value的大小进行排序
- IDEA Maven不见了
- NoSql之Redis持久化
- Java语言程序设计考试安排
- 文章标题
- 推荐系统_推荐系统的常用评测指标
- Map的插入操作和按照value排序
- LeetCode 34. Search for a Range
- java 线程池和队列的小研究
- Ultra Pull To Refresh 下拉刷新 替代PullToRefresh
- JUnit4测试基于Spring的Action组件
- 多线程学习(四)线程的交互
- 2016从零开始纯C语言、C++语言一步一步完成RPG大型游戏开发
- git的安装和使用Mac版本,本地代码仓库文件的删除和重新导入代码
- 【checkpoint】深入了解checkpoint过程