map插入自定义对象总结
2023-06-13 09:15:05 时间
难道插入map还有什么讲究吗?我们且看map在STL中的定义方法:
template<classKey,classT,classCompare=less<Key>,classAlloc=alloc>
第二个参数T是值类型
第三个参数Compare是比较函数(仿函数)
第四个参数是内存配置对象
map内部存储机制实际是以红黑树为基础,红黑树在插入节点时,必须依照大小比对之后在一个合适的位置上执行插入动作。所以作为关键字,起码必须有“<”这个比较操作符。我们知道,int,float,enum,size_t等等简单关键字,都有内置的比较函数,与map搭配无论是插入还是查找,都没什么问题。但是作为复杂数据类型,如果没有明确定义“<”比较操作符,就不能与map直接搭配使用,除非我们自己定义第三个参数。
a)关键字明确定义“<”比较操作符
b)没有“<”比较操作符,自定义仿函数替代第三个参数Compare,该仿函数实现“()”操作符,提供比较功能。插入时各节点顺序以该仿函数为纲。
#include<map>
intmain()
{
std::map<std::pair<int,int>,int>res;
res.insert(std::make_pair(12,33),33);
}
这个程序一定失败,如果非要如此使用,上述a方法显然不适合,std::pair是已定义好的结构体不可修改。只能使用b方法了,定义一个比较类改造如下:
#include<map>
structcomp
{
typedefstd::pair<int,int>value_type;
booloperator()(constvalue_type&ls,constvalue_type&rs)
{
returnls.first<rs.first||(ls.first==rs.first&&ls.second<rs.second);
}
};
intmain()
{
std::map<std::pair<int,int>,int,comp>res;
res.insert(std::make_pair(std::make_pair(12,33),33));
res.insert(std::make_pair(std::make_pair(121,331),331));
res.insert(std::make_pair(std::make_pair(122,332),332));
std::map<std::pair<int,int>,int,comp>::iteratorit=res.find(std::make_pair(121,331));
if(it==res.end())
printf("NULL"n");
else
printf("%d%d%d"n",it->first.first,it->first.second,it->second);
return0;
}
以结构体或类为关键字插入map
#include<map>
structst
{
inta,b;
st():a(0),b(0){}
st(intx,inty):a(x),b(y){}
};
intmain()
{
std::map<structst,int>res;
res.insert(std::make_pair(st(1,2),12));
res.insert(std::make_pair(st(30,4),34));
res.insert(std::make_pair(st(5,6),56));
std::map<structst,int>::iteratorit=res.find(st(30,4));
if(it==res.end())
printf("NULL"n");
else
printf("first:%dsecond:%d%d"n",it->first.a,it->first.b,it->second);
return0;
}
编译这个程序也是错误的,错误意思大概也是没有定义“<”比较函数。因为structst是我们自己定义的结构体,所以修改这个程序可以使用上面a、b两种方法。我们先谈第一种,第一次修改时我也搞错了,我是这样定义比较函数的。
structst
{
inta,b;
st():a(0),b(0){}
st(intx,inty):a(x),b(y){}
booloperator<(conststructst&rs){return(this->a<rs.a||(this->a==rs.a&&this->b<rs.b));}
};
按照这个改动再次编译程序还是错误,有个如下这样的提示:
/usr/include/c++/3.2.3/bits/stl_function.h:197:passing`constst"as`this"argumentof`boolst::operator<(constst&)"discardsqualifiers
为什么会出现这个问题呢?我们深入STL的源代码看下。既然说是/usr/include/c++/3.2.3/bits/stl_function.h的197行出了问题,且看这行是什么。
193///Oneofthe@links20_3_3_comparisonscomparisonfunctors@endlink.
194template<class_Tp>
195structless:publicbinary_function<_Tp,_Tp,bool>
196{
197 booloperator()(const_Tp&__x,const_Tp&__y)const{return__x<__y;}
198};
structst中的“<”在编译后真正是什么样子呢?大概是booloperator<(structst&ls,conststructst&rs)。在less调用这个比较符时,它都是以const方式传入,不可能再以非const方式调用,故出错。修正如下:
structst
{
inta,b;
st():a(0),b(0){}
st(intx,inty):a(x),b(y){}
friendbooloperator<(conststructst&ls,conststructst&rs);
};
inlinebooloperator<(conststructst&ls,conststructst&rs)
{return(ls.a<rs.a||(ls.a==rs.a&&ls.b<rs.b));}
以友联函数代替函数内部定义的比较操作符,STL内部也多是以这种方式定义的。如果我非要以内部定义的方式呢?可以使用b方法,我们自定义一个比较仿函数,替代默认的less。
map容器不允许键值重复,在执行插入操作后,可以凭借该返回值获取操作结果。返回值是一个迭代器和布尔值的键值对,迭代器指向map中具有该值的元素,布尔值表示是否插入成功。如果布尔值为true,表示插入成功,则迭代器为新插入值在map中的位置;布尔值为false,表示插入失败(已经存在该值),迭代器为原有值在map中的位置。
相关文章
- golang中的map并发读写问题: Golang 协程并发使用 Map 的正确姿势
- List<Map>聚合为单个Map<List>
- java 对象转map,去掉null
- java map 转string_java-将Map <String,Object>转换为Map <String,String>
- 对象转map(object转map)
- DataFrame的apply()、applymap()、map()方法[通俗易懂]
- Map集合转换成实体类对象,实体类对象转换为map集合,互转工具类「建议收藏」
- js判断map是否为空
- 大数据必学Java基础(五十九):Map接口源码部分
- golang map 有序_有序化最重要的手法是
- js中map遍历数组对象_js遍历数组
- Java的fastjson对象,JSON,字符串,map之间的互转
- p5.js map映射
- Pandas的apply, map, transform介绍和性能测试
- 比较Python中的列表推导式和map(),filter()函数
- Go语言遍历map(访问map中的每一个键值对)
- js模仿java的Map集合,实现功能详解编程语言
- C++STL中map容器的说明和使用技巧(杂谈)详解编程语言
- Java中遍历Map对象详解编程语言
- 总结的一些json格式和对象/String/Map/List等的互转工具类详解编程语言
- Oracle 视图 DBA_WORKLOAD_SQL_MAP 官方解释,作用,如何使用详细说明
- Oracle 视图 V$MAP_SUBELEMENT 官方解释,作用,如何使用详细说明
- Java Map.clear()方法:从Map集合中移除所有映射关系
- Oracle应用Map参数的优势初探(map参数 oracle)
- 集Oracle中存储Map集的新方法(oracle保存map)
- 解决Redis频繁修改Map难题(redis频繁修改map)
- 基于Redis集群的Map数据结构的删除(redis集群map删除)
- 探索Redis中的Map之谜(redis里查map)
- 灵活运用Redis如何实现设置多个Map(redis设置多个map)
- java中关于Map的三种遍历方法详解
- java集合map取key使用示例java遍历map
- 使用array_map简单搞定PHP删除文件、删除目录
- Java中Map的遍历方法及性能测试