若干问题:

struct Node {
int k, b;
friend bool operator <(Node a, Node b) {
return a.k < b.k;
}
}node1, node2; map<Node, int> mp; int main() { node1.k = ;
node1.b = ;
mp[node1] = ;
node1.k = ;
node1.b = ;
printf("%d\n", mp.count(node1));
//输出1
return ;
}
struct Node {
int k, b;
friend bool operator <(Node a, Node b) {
if (a.k != b.k) return a.k < b.k;
else return a.b < b.b;
}
}node1, node2; map<Node, int> mp; int main() { node1.k = ;
node1.b = ;
mp[node1] = ;
node1.k = ;
node1.b = ;
printf("%d\n", mp.count(node1));
//输出0
return ;
}

1、以结构体为Key

map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),红黑树具有对数据自动排序(默认是以less<>升序对元素排序(排序准则也可以修改))的功能,因此在map内部所有的关键字都是有序的。当key为基本数据类型时,不存在问题。但是当关键字是一个结构体时,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候就会出错,下面给出解决这个问题的方法:

对操作符"<"进行重载(不可以重载大于号)

#include <map>
#include <iostream>
#include <string>
using namespace std;
struct Node{
int id;
string name;
friend bool operator < (Node a,Node b)
{
//指定排序策略,按id排序,如果id相等的话,按name排序
if (a.id != b.id) return a.id > b.id;
else return a.name > b.name;
}
}StudentInfo, *pStudentInfo; //学生信息 int main(){
int nSize;
//用学生信息映射分数
map<Node, int> mapStudent;
map<Node, int>::iterator it; StudentInfo.id = ;
StudentInfo.name = "student_one";
mapStudent.insert(pair<Node, int>(StudentInfo, ));
StudentInfo.id = ;
StudentInfo.name = "student_two";
mapStudent.insert(pair<Node, int>(StudentInfo, )); for (it = mapStudent.begin(); it != mapStudent.end(); it++)
cout << it->first.id << " " << it->first.name << " " << it->second << endl; }
printf("%d",mp.find(StudentInfo)->second);
printf("%d",mp[StudentInfo]);  都可以

重载的部分可以写到结构体外,但有三点要求:

1、把friend去掉,把小于号改成一对小括号。

2、用struct把函数包装起来。

3、map的定义方式改为map<Node, int, cmp> mapStudent;

如:

#include <map>
#include <iostream>
#include <string>
using namespace std;
struct Node{
int id;
string name; }StudentInfo, *pStudentInfo; //学生信息 struct cmp {
bool operator () (Node a, Node b)
{
//指定排序策略,按nID排序,如果nID相等的话,按strName排序
if (a.id != b.id) return a.id > b.id;
else return a.name > b.name;
}
};
map<Node, int, cmp> mapStudent;
map<Node, int, cmp>::iterator it;
int main(){
int nSize;
//用学生信息映射分数 StudentInfo.id = ;
StudentInfo.name = "student_one";
mapStudent.insert(pair<Node, int>(StudentInfo, ));
StudentInfo.id = ;
StudentInfo.name = "student_two";
mapStudent.insert(pair<Node, int>(StudentInfo, )); for (it = mapStudent.begin(); it != mapStudent.end(); it++)
cout << it->first.id << " " << it->first.name << " " << it->second << endl; }
printf("%d",mp.find(StudentInfo)->second);
printf("%d",mp[StudentInfo]); 也可以

2、以结构体指针为Key,可以不重载<号,因为地址可以比较大小。

但是也可以根据指针指向的内容重载小于号,但此时重载函数必须放在自定义的结构体外面。(原因不详。。。)

#include <map>
#include <iostream>
#include <cstdio>
using namespace std; struct Key
{
int x,y;
}*ptr; struct CompareKey
{
bool operator()(Key *in_a, Key *in_b)
{
return in_a->x < in_b->x;
}
}; map<Key *, int, CompareKey> mp; int main()
{ for (int i = ; i < ; i++)
{
Key *k = new Key;
if(i==) ptr=k; k->x = i;
k->y = i+; mp.insert(make_pair(k, i));
} map<Key *, int, CompareKey>::iterator it;
for(it=mp.begin();it!=mp.end();it++){
if(it->first==ptr){
printf("%d %d %d\n",it->first->x,it->first->y,it->second);
}
} }

2、以自定义struct或struct指针作为map的Key的更多相关文章

  1. 指针做MAP的KEY的TEST

    用struct做map的key会需要"operator <"等等,还会出现奇怪的问题可能. 试了下用指针做key,看看效果: #include <iostream> ...

  2. typedef&nbsp;struct与struct的区别

    typedef struct与struct的区别 1. 基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据 ...

  3. 结构体struct sockaddr_in, struct sockaddr,struct in_addr

    一.结构体 struct sockaddr_in,  struct sockaddr,  struct in_addr struct sockaddr_in,  struct sockaddr,str ...

  4. typedef struct与struct定义结构体

    今天在定义结构体的时候发现typedef struct与struct定义结构体有一些不同之处: 结构也是一种数据类型, 能够使用结构变量, 因此,  象其他 类型的变量一样, 在使用结构变量时要先对其 ...

  5. linux网络接口,struct ifreq struct ifconf结构

    网络相关的ioctl请求的request参数及arg地址必须指向的数据类型如下表所示: 接口 SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFBRDADDR SI ...

  6. map的key 为指针

    STL中map的key能否用char *呢?当然可以! 在程序中需要用到一个map,本来是这样写的,map<string, int> mapStr; 为了追求效率,把string改成了ch ...

  7. 关于set或map的key使用自定义类型的问题

    我们都知道set或map的key使用自定义类型时必须重载<关系运算符 但是,还有一个条件,所调用重载的小于操作符,使用的对象必须是const 而对象调用的方法也必须是const的 1 #incl ...

  8. [C++学习笔记14]动态创建对象(定义静态方法实现在map查找具体类名对应的创建函数,并返回函数指针,map真是一个万能类)good

    [C++学习笔记14]动态创建对象   C#/Java中的反射机制 动态获取类型信息(方法与属性) 动态创建对象 动态调用对象的方法 动态操作对象的属性 前提:需要给每个类添加元数据 动态创建对象 实 ...

  9. Flink 自定义source和sink,获取kafka的key,输出指定key

    --------20190905更新------- 沙雕了,可以用  JSONKeyValueDeserializationSchema,接收ObjectNode的数据,如果有key,会放在Objec ...

随机推荐

  1. 田螺便利店—ipconfig命令不是内部命令或外部命令怎么解决?

    查询网卡ID在运行后输入ipconfig/all点回车后提示ipconfig不是内部或外部命令,也不是可运行的程序或批处理文件? 首先确认你的输入是无误的,确保输入无误,仍提示 ipconfig 不是 ...

  2. 学号 20155219 《Java程序设计》第1周学习总结

    学号 20155219 <Java程序设计>第1周学习总结 教材学习内容总结 JVM:是JAVA程序唯一认识的操作系统,其可执行文件为.class文档:具有让Java程序跨平台的功能.负责 ...

  3. HDU 1000

    A + B Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...

  4. PS学习之动态表情制作

    准备素材 1. 2. 3. 4. 最后效果图: 在PS中打开四个图片 另外新建一个文件 用魔棒工具抠图 点击白色位置 右键选择反向 右键人物 选择拷贝的图层 重复,将四个图片扣好 拖到新建的文件里 如 ...

  5. java依赖注入(injection)

    和SpringSource分别通过其开源项目Guice及Spring Framework提供了依赖注入的功能.然而直到现在开发者也没有一种标准的.独立于供应商的方式从而无需修改其源文件就能在这些框架之 ...

  6. python------软件目录结构规范

    一. 目录结构 www.cnblogs.com/alex3714/articles/5765046.html print(__file__) 获得相对路径 import osprint(os.path ...

  7. idea使用的JDK版本1.9换成1.8后相关的更改设置

    File——>Project Structure 一.查看Project中的jdk 1.检查Project SDK:中jdk 版本是否为1.8版本 2.检查Project language le ...

  8. 推荐一个 .Net Core 的 Redis 库

    这是一个网友写的,原文如下: https://www.cnblogs.com/kellynic/p/9803314.html

  9. P2P Downloader

    P2P Downloader , 当然就是 P2P 下载器了 , 就是和 比特精灵 差不多的那种 .  ^ ^ 不过这个项目没有代码 , 懒得写代码了 , 就文字描述一下吧 .   ^ ^ P2P 下 ...

  10. mysql之 xtrabackup-2.4.12 安装

    版本说明:备份工具:percona-xtrabackup-2.4.12-Linux-x86_64.libgcrypt11os:centos 6.5 1.解压安装包tar zxvf percona-xt ...