1. 概述

STL中像set和map这样的容器是通过红黑树来实现的,插入到容器中的对象是顺序存放的,采用这样的方式是非常便于查找的,查找效率能够达到O(log n)。所以如果有查找数据的需求,可以采用set或者map。

但是我们自定义的结构体或者类,无法对其比较大小,在放入到容器中的时候,就无法正常编译通过,这是set/map容器的规范决定的。要将自定义的结构体或者类存入到set/map容器,就需要定义一个排序的规则,使其可以比较大小。最简单的办法就是在结构体或者类中加入一个重载小于号的成员函数,这样在存数据进入set/map中时,就可以根据其规则排序。

2. 实例

在这里就写了一个简单的例子,将自定义的一个二维点存入set/map,并查找其中存入的数据:

#include <iostream>
#include <map>
#include <set>
#include <string> using namespace std; const double EPSILON = 0.000001; // 2D Point
struct Vector2d
{
public:
Vector2d()
{
} Vector2d(double dx, double dy)
{
x = dx;
y = dy;
} // 矢量赋值
void set(double dx, double dy)
{
x = dx;
y = dy;
} // 矢量相加
Vector2d operator + (const Vector2d& v) const
{
return Vector2d(x + v.x, y + v.y);
} // 矢量相减
Vector2d operator - (const Vector2d& v) const
{
return Vector2d(x - v.x, y - v.y);
} //矢量数乘
Vector2d Scalar(double c) const
{
return Vector2d(c*x, c*y);
} // 矢量点积
double Dot(const Vector2d& v) const
{
return x * v.x + y * v.y;
} //向量的模
double Mod() const
{
return sqrt(x * x + y * y);
} bool Equel(const Vector2d& v) const
{
if (abs(x - v.x) < EPSILON && abs(y - v.y) < EPSILON)
{
return true;
}
return false;
} bool operator == (const Vector2d& v) const
{
if (abs(x - v.x) < EPSILON && abs(y - v.y) < EPSILON)
{
return true;
}
return false;
} bool operator < (const Vector2d& v) const
{
if (abs(x - v.x) < EPSILON)
{
return y < v.y ? true : false;
}
return x<v.x ? true : false;
} double x, y;
}; int main()
{
{
set<Vector2d> pointSet;
pointSet.insert(Vector2d(0, 11));
pointSet.insert(Vector2d(27, 63));
pointSet.insert(Vector2d(27, 15));
pointSet.insert(Vector2d(0, 0));
pointSet.insert(Vector2d(67, 84));
pointSet.insert(Vector2d(52, 63)); for (const auto &it : pointSet)
{
cout << it.x << '\t' << it.y << endl;
} auto iter = pointSet.find(Vector2d(27, 63));
if (iter == pointSet.end())
{
cout << "未找到点" << endl;
}
else
{
cout << "可以找到点" << endl;
}
} {
map<Vector2d, string> pointSet;
pointSet.insert(make_pair(Vector2d(52, 63), "插入时的第1个点"));
pointSet.insert(make_pair(Vector2d(27, 63), "插入时的第2个点"));
pointSet.insert(make_pair(Vector2d(0, 11), "插入时的第3个点"));
pointSet.insert(make_pair(Vector2d(67, 84), "插入时的第4个点"));
pointSet.insert(make_pair(Vector2d(27, 15), "插入时的第5个点"));
pointSet.insert(make_pair(Vector2d(0, 0), "插入时的第6个点")); for (const auto &it : pointSet)
{
cout << it.first.x << ',' << it.first.y << '\t' << it.second << endl;
} auto iter = pointSet.find(Vector2d(27, 63));
if (iter == pointSet.end())
{
cout << "未找到点" << endl;
}
else
{
cout << "可以找到点" << endl;
}
}
}

其中的关键就是在点的结构体中重载了<符号的比较函数,规定首先比较y的大小,其次在比较x的大小:

bool operator < (const Vector2d& v) const
{
if (abs(x - v.x) < EPSILON)
{
return y < v.y ? true : false;
}
return x<v.x ? true : false;
}

最终的运行结果如下:

C++中自定义结构体或类作为关联容器的键的更多相关文章

  1. [转]C#中的结构体与类的区别

    C#中的结构体与类的区别   经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字cla ...

  2. 浅析C#中的结构体和类

    类和结构是 .NET Framework 中的常规类型系统的两种基本构造. 两者在本质上都属于数据结构.封装着一组总体作为一个逻辑单位的数据和行为. 数据和行为是该类或结构的"成员" ...

  3. [UE4]自定义结构体、类、数据表

    自定义数据表: #pragma once #include "CoreMinimal.h" #include "Engine/UserDefinedStruct.h&qu ...

  4. C#中的结构体与类的区别

    经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字class 定义结构使用关键字str ...

  5. C#中的结构体与类的区别 (转载)

    经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字class 定义结构使用关键字str ...

  6. OpenCV中的结构体、类与Emgu.CV的对应表

    OpenCv中的 C 结构 OpenCV中的 C++ 封装 Emgu.CV中的 C# 封装 OpenCV 和 Emgu.CV 中的结构罗列 谢谢阅读,有误希望指正 原文地址 Basic Structu ...

  7. C++ 自定义结构体和类 内存对齐

    为什么要提出内存对齐? 比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个doubl ...

  8. C C++ 中结构体与类

    先来说说C和C++中结构体的不同 a) C语言中的结构体不能为空,否则会报错 1>d:\myproject\visual studio 2013\projects\myc++\main.c(71 ...

  9. C++中的结构体

    http://zhidao.baidu.com/link?url=8OYQSKV9mvSBc6Hkf9NsLQmipSge9VCZDJQGAZZs5PCBQ54UTmK98VRmAklEEAFYu7d ...

  10. C语言中的结构体和C++中的结构体以及C++中类的区别

    c++中结构体可以定义一个函数 C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数. C++中的结构体和类的异同: 一. ...

随机推荐

  1. 基于 Angular和Material autocomplete组件再封装的可双向绑定key-value的可输入下拉框

    GitHub: https://github.com/Xinzheng-Li/AngularCustomerComponent 效果图:为了方便使用,把许多比如ADD的功能去了,可以在使用后自行实现. ...

  2. 区间检测(range)

    区间检测(range) 时间限制: 1 Sec  内存限制: 128 MB 题目描述 给定一个长度为n的序列,进行m次检测,每次检测某个区间中,是否有重复的数. 输入 第一行,两个整数n和m,表示序列 ...

  3. 2020 5 17 codeforces

    cf还没结束,就开始写总结了.cf确实是个好东西,能够直接暴露出弱点和增加刷题量.以后还是要多打打的.这次我发现自己的码力还是不行.一个二分都要调好久.唉T1sb题,就是入门用的.题目看不懂...写了 ...

  4. CSP-J 2022 游记

    10.9 早上睡到 7:00. 上午继续学习 Vim,学习哈希表. 10.11 白天线段树,区间加从六参改成四参就过了 晚上模拟赛,感觉良好 10.16 膜你赛,std变量命名毒瘤. 想用 geogb ...

  5. 基于LangChain的LLM应用开发2——模型、提示和输出解析

    本次会讲解LangChain的三个基本组件:模型.提示和解析器. 名词解析 模型(Models):是指作为基础的大语言模型.LangChain中通过ChatOpenAI或者AzureChatOpenA ...

  6. java值传递机制

    目录 1. 基本数据类型 2. 引用数据类型 3. 总结 1. 基本数据类型 public class ValueTransferTest { public static void main(Stri ...

  7. 一元多项式求和(c++源码)

    LinkList.h #ifndef LINKLIST_H_ #define LINKLIST_H_ #include<stdio.h> template<class T> s ...

  8. 二。docker安装mysql 并配置

    1.docker安装mysql 1.1使用docker拉取mysql的镜像 docker pull mysql:5.7 1.2通过镜像启动 docker run -p 3306:3306 --name ...

  9. webservice soap hessian

    http://www.blogjava.net/freeman1984/archive/2010/01/20/310198.html http://www.cnblogs.com/JeffreySun ...

  10. 从DPlayer说起,有哪些开源的H5播放器

    引言 ​ H5指的是HTML5,也就是介绍网页播放器(只是列出而已).首先我不是什么大佬,并没有完全体验过以下我会介绍的全部播放器:其次,因为我水平比较低,主要介绍拥有中文文档的播放器,不了解开发的朋 ...