我的编程空间,编程开发者的网络收藏夹
学习永远不晚

map插入自定义对象总结

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

map插入自定义对象总结

难道插入map还有什么讲究吗?我们且看map在STL中的定义方法:
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
第一个参数Key是关键字类型
第二个参数T是值类型
第三个参数Compare是比较函数(仿函数)
第四个参数是内存配置对象

map内部存储机制实际是以红黑树为基础,红黑树在插入节点时,必须依照大小比对之后在一个合适的位置上执行插入动作。所以作为关键字,起码必须有“<”这个比较操作符。我们知道,int,float,enum,size_t等等简单关键字,都有内置的比较函数,与map搭配无论是插入还是查找,都没什么问题。但是作为复杂数据类型,如果没有明确定义“<”比较操作符,就不能与map直接搭配使用,除非我们自己定义第三个参数。

在选择map的关键字时,注意以下两点,同时这两点也是改错的方法:
a) 关键字明确定义“<”比较操作符
b) 没有“<”比较操作符,自定义仿函数替代第三个参数Compare,该仿函数实现“()”操作符,提供比较功能。插入时各节点顺序以该仿函数为纲。

以std::pair为关键字掺入map
下面我们先写一个有错误的函数,在分析错误原因之后,逐步进行修正。

复制代码 代码如下:

#include <map>

int main()
{
std::map<std::pair<int, int>, int> res;
       res.insert(std::make_pair(12,33), 33);
}

这个程序一定失败,如果非要如此使用,上述a方法显然不适合,std::pair是已定义好的结构体不可修改。只能使用b方法了,定义一个比较类改造如下:
复制代码 代码如下:

#include <map>

struct comp
{
       typedef std::pair<int, int> value_type;
       bool operator () (const value_type & ls, const value_type &rs)
       {
              return ls.first < rs.first || (ls.first == rs.first && ls.second < rs.second);
       }
};

int main()
{
       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>::iterator it = 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);

    return 0;
}

以结构体或类为关键字插入map
复制代码 代码如下:

#include <map>

struct st
{
       int a, b;

       st():a(0), b(0){}
       st(int x, int y):a(x), b(y){}
};

int main()
{
       std::map<struct st, 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<struct st, int>::iterator it = res.find(st(30,4));

       if (it == res.end())
              printf("NULL"n");
       else
              printf("first:%d second:%d %d"n", it->first.a, it->first.b, it->second);

       return 0;
}

编译这个程序也是错误的,错误意思大概也是没有定义“<”比较函数。因为struct st是我们自己定义的结构体,所以修改这个程序可以使用上面a、b两种方法。我们先谈第一种,第一次修改时我也搞错了,我是这样定义比较函数的。
复制代码 代码如下:

struct st
{
       int a, b;

       st():a(0), b(0){}
       st(int x, int y):a(x), b(y){}
bool operator < (const struct st &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 `const st' as `this' argument of `bool st::operator<(const st&)' discards qualifiers

为什么会出现这个问题呢?我们深入STL的源代码看下。既然说是/usr/include/c++/3.2.3/bits/stl_function.h的197行出了问题,且看这行是什么。
复制代码 代码如下:

   193 /// One of the @link s20_3_3_comparisons comparison functors@endlink.
   194 template <class _Tp>
   195 struct less : public binary_function<_Tp,_Tp,bool>
   196 {
   197       bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; }
   198 };

struct st中的“<”在编译后真正是什么样子呢?大概是bool operator < (struct st &ls, const struct st &rs)。在less调用这个比较符时,它都是以const方式传入,不可能再以非const方式调用,故出错。修正如下:
复制代码 代码如下:

struct st
{
       int a, b;

       st():a(0), b(0){}
       st(int x, int y):a(x), b(y){}
       friend bool operator < (const struct st &ls, const struct st &rs);
};
inline bool operator < (const struct st &ls, const struct st &rs)
{return (ls.a < rs.a || (ls.a == rs.a && ls.b < rs.b));}

以友联函数代替函数内部定义的比较操作符,STL内部也多是以这种方式定义的。如果我非要以内部定义的方式呢?可以使用b方法,我们自定义一个比较仿函数,替代默认的less。

插入函数返回值
在map容器中插入数据有很多函数可用,这里只讨论最普通的insert操作,在STL中它是这样定义的。
pair<iterator, bool> insert(const value_type& x);
map容器不允许键值重复,在执行插入操作后,可以凭借该返回值获取操作结果。返回值是一个迭代器和布尔值的键值对,迭代器指向map中具有该值的元素,布尔值表示是否插入成功。如果布尔值为true,表示插入成功,则迭代器为新插入值在map中的位置;布尔值为false,表示插入失败(已经存在该值),迭代器为原有值在map中的位置。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

map插入自定义对象总结

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

map插入自定义对象总结

黑树在插入节点时,必须依照大小比对之后在一个合适的位置上执行插入动作。所以作为关键字,起码必须有“<”这个比较操作符
2022-11-15

Python中导入自定义模块的几种方法总结

这篇文章主要介绍了Python中导入自定义模块的几种方法总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-01-04

Android基础篇-对话框总结(普通对话框,单选对话框,多选对话框,自定义对话框)

一:AlterDialog对话框2:对话框圆角显示(在drawable下创建radius_bomb_box.xml)3:Styles样式设置@color/colorPrimary@color/colorPrimaryDark@color/c
2022-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录