【map】【unordered_map】map和unordered_map中键类型为自定义类型的操作

STL中map的底层为红黑树,所以查找的时间复杂度为O(logn)

unordered_map是根据哈希值(遇到哈希值相同时用==号比较)寻找键,所以时间复杂度为O(1)

键类型为自定义类型时,map需要重载键类型的<符号,unordered_map需要定义键类型的哈希函数(在类外定义),以及重载键类型的==符号。

class person1
{
public:
    string name;
    int age;
    person1(string s,int i):name(s),age(i){}
	//map必须重载键类型的<符号
	const bool operator<(const person1 &a)const
	{
		if(age!=a.age)
			return age<a.age;
		else
			return name<a.name;
	}
};  

class person2
{
public:
    string name;
    int age;
    person2(string s,int i):name(s),age(i){}  

	//unordered_map必须重载键类型的==符号,才能在哈希值相等的情况下找到准确的键值对
	const bool operator==(const person2 &a)const
	{
		return age==a.age && name==a.name;
	}
}; 

//person2类的哈希函数
struct person2_hash
{
	//unordered_map必须定义键类型的哈希函数
	size_t operator()(const person2 &p)const
    {
        return hash<int>()(p.age)+hash<char>()(p.name[0]);
    }
};

//测试代码
//map操作
map<person1,string> map_person;
person1 p1("Tom",15);
person1 p2("Tim",22);
//map_person.emplace("Tim",22,"driver"); 该行语法错误
map_person[p1]="student";
map_person[p2]="driver";
cout<<map_person[p1]<<endl;//输出 student
cout<<map_person[p2]<<endl;//输出 driver

//unordered_map操作
unordered_map<person2,string,person2_hash> unordered_person;
person2 x1("Ton",14);//x1和x2的哈希值相等
person2 x2("Tim",14);
person2 x3("John",50);
unordered_person[x1]="I am Ton";
unordered_person[x2]="I am Tim";
unordered_person[x3]="I am John";
cout<<unordered_person[x1]<<endl;//输出  I am Ton
cout<<unordered_person[x2]<<endl;//输出  I am Tim
cout<<unordered_person[x3]<<endl;//输出  I am John
时间: 2024-12-11 13:02:36

【map】【unordered_map】map和unordered_map中键类型为自定义类型的操作的相关文章

《Go语言实战》Go 类型:基本类型、引用类型、结构类型、自定义类型

Go 语言是一种静态类型的编程语言,所以在编译器进行编译的时候,就要知道每个值的类型,这样编译器就知道要为这个值分配多少内存,并且知道这段分配的内存表示什么. 提前知道值的类型的好处有很多,比如编译器可以合理的使用这些值,可以进一步优化代码,提高执行的效率,减少 bug 等等. 基本类型 基本类型是 Go 语言自带的类型,比如 数值.浮点.字符串.布尔.数组 及 错误 类型,他们本质上是原始类型,也就是不可改变的,所以对他们进行操作,一般都会返回一个新创建的值,所以把这些值传递给函数时,其实传递

springmvc 类型转换器 自定义类型转换器

自定义类型转换器的步骤: 1.定义类型转换器 2.类型转换器的注册(在springmvc配置文件处理) 来解决多种日期格式的问题:

【干货】C++通过模板特化实现类型萃取实例--实现区分基本类型与自定义类型的memcpy

类型萃取是一种常用的编程技巧,其目的是实现不同类型数据面对同一函数实现不同的操作,如STL中cout的实现,它与类封装的区别是,我们并不用知道我们所调用的对象是什么类型,类型萃取是编译器后知道类型,先实现,而类的封装则是先定义类型,后实现方法.在这里我们可以用模板的特化实现其编程思想. 我们以memcpy为例,当我们拷贝的是基本类型时,只用拷贝所传递指针上的数据,如果是string类型呢,我们则需要在堆上开辟空间,所传递的指针如果被直接复制,则有可能(vs下的string类型的实现原理是若字符串

普通类型与自定义类型之间的转化

@2019-06-11 [小记] 1 typedef union MultiByte 2 { 3 unsigned int word; 4 unsigned char byte[sizeof(unsigned int)]; 5 }multiByte_t; 6 7 float _value_from_prase(uint32_t arg) 8 { 9 /* 方法一 */ 10 multiByte_t *parse = (multiByte_t *)&arg; 11 12 /* 方法二 */ 13

Hibernate中的自定义类型——UserType、CompositeUserType

一.UserType Hibernate拥有自定义映射表属性的机制,主要通过实现接口UserType,具体的UserType: import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import net.sf.hibernate.HibernateException; /** * @author hy-he * */ public interface UserType

OC中保存自定义类型对象的持久化方法

OC中如果要将自定义类型的对象保存到文件中,必须进行以下三个条件: 想要把存放自定义类型的数组进行 持久化(就是将内存中的临时数据以文件<数据库等>的形式写到磁盘上)必须满足: 1. 自定义对象必须要序列化(将数据有序的存放) 2. 需要使用归档来进行持久化 3. 如果要加载持久化文件需要进行反序列化(就是将有序存放的数据读取并变成自定义对象) 第一要将自定义类型序列化以及第三步并将文件反序列化必须实现OC中的  <NSCoding>协议. 以Student类为例 @interfa

oracle 自定义类型 type / create type

一:Oracle中的类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarchar2. 2.数值类型.如:int.number(p,s).integer.smallint. 3.日期类型.如:date.interval.timestamp. 4.PL/SQL类型.如:pls_integer.binary_integer.binary_double(10g).binary_float(10g).boolean.plsql类型是不能在sql环境中使

Struts2 自定义类型转换器

Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性 用date类型是可以接收到的,但是如果传的是20101112这样类型的字符串,用date类型是获取不到,并且会出现错误的,struts2提供了一 种类型转换器供我们使用. 以下为局部类型转换器的开发步骤a.首先要写一个类来继承DefaultTypeConverterb.然后覆盖convertValue

Struts2之自定义类型转换器

Struts2自定义类型转换器分为局部类型转换器和全局类型转换器 (1)局部类型转换器 如果页面传来一个参数reg.action?birthday=2010-11-12到后台action,然后属性用date类型是可以接收到的,但是如果传的是20101112这样类型的字符串,用date类型是获取不到,并且会出现错误的,struts2提供了一种类型转换器供我们使用. 以下为局部类型转换器的开发步骤a.首先要写一个类来继承DefaultTypeConverterb.然后覆盖convertValue这个