【C++中map和unordered_map存储自定义类型需要做什么】

目录

一、map存储自定义类型

 二、unordered_map存储自定义类型


一、map存储自定义类型

 需要传入的参数是key-value键值对,和仿函数类型

 对于内置类型,int、double、char重载了operator<所以传入less仿函数不会出错

但是对于自定义类型,如果不重载operator<就会出错

比如下面:传入自定义类型直接报错


#include <map>
#include <iostream>

class Person
{
public:
	int _age;

	Person(int age = -1) :_age(age)
	{}
};

int main()
{
	std::map<Person, int> um;
	um.insert(std::make_pair<Person, int>(Person(1), 1));
	um.insert(std::make_pair<Person, int>(Person(2), 1));

	for (auto& e : um)
	{
		std::cout << e.first._age << " " << e.second << std::endl;
	}
	return 0;
}

存储自定义类型进行传参的两种方法:

方法一:重载operator<


#include <map>
#include <iostream>

class Person
{
public:
	int _age;

	Person(int age = -1) :_age(age)
	{}

	// 重载operator<
	bool operator<(const Person& p) const
	{
		return _age < p._age;
	}
};

int main()
{
	std::map<Person, int> um;
	um.insert(std::make_pair<Person, int>(Person(1), 1));
	um.insert(std::make_pair<Person, int>(Person(2), 1));

	for (auto& e : um)
	{
		std::cout << e.first._age << ":" <<  e.second << std::endl;
	}

	return 0;
}

 方法二:自己定义比较规则:传入仿函数类型


#include <map>
#include <iostream>

class Person
{
public:
	int _age;

	Person(int age = -1):_age(age)
	{}
};

class PersonCmp
{
public:
	bool operator()(const Person& p1, const Person& p2) const
	{
		return p1._age < p2._age;
	}
};

int main()
{
	// 自定定义一个仿函数比较规则
	std::map<Person, int, PersonCmp> um;
	um.insert(std::make_pair<Person, int>(Person(1), 1));
	um.insert(std::make_pair<Person, int>(Person(2), 1));

	for (auto& e : um)
	{
		std::cout << e.first._age <<  " " << e.second << std::endl;
	}
	return 0;
}

 二、unordered_map存储自定义类型

 第一个参数:传入key值

第二个参数:传入T值

第三个参数哈希函数

对于内置类型支持可以支持哈希函数

 

第四个参数key的比较方式

对于内置类型是重载了比较方式的

 传入自定义类型什么也不做:
 


#include <iostream>
#include <unordered_map>

class Person
{
public:
	int _age;

	Person(int age = -1) :_age(age)
	{}
};

int main()
{
	std::unordered_map<Person, int> um;
	um.insert(std::make_pair<Person, int>(Person(1), 1));
	um.insert(std::make_pair<Person, int>(Person(2), 1));

	for (auto& e : um)
	{
		std::cout << e.first._age << " " << e.second << std::endl;
	}
	return 0;
}

 这个是会出问题的,重载operator ==,因为哈希表需要按照key进行查找,需要进行比较

以及定义哈希函数,因为没有系统的hash函数没有对自定义类型进行哈希

方法一:自定义类中重载operator == 和自定义hash函数,不传入第四个参数


#include <iostream>
#include <unordered_map>
#include <functional>

class Person
{
public:
	int _age;

	Person(int age = -1) :_age(age)
	{}

	bool operator == (const Person& p) const
	{
		return _age == p._age;
	}
};

struct PersonHash
{
public:
	size_t operator()(const Person& p) const
	{
		return std::hash<int>()(p._age);
	}
};

int main()
{
	std::unordered_map<Person, int, PersonHash> um;
	um.insert(std::make_pair<Person, int>(Person(1), 1));
	um.insert(std::make_pair<Person, int>(Person(2), 1));

	for (auto& e : um)
	{
		std::cout << e.first._age << " " << e.second << std::endl;
	}
	return 0;
}

 

 方法二:自定义hash函数和自定义key的比较规则


#include <iostream>
#include <unordered_map>
#include <functional>

class Person
{
public:
	int _age;

	Person(int age = -1) :_age(age)
	{}
};

struct PersonHash
{
public:
	size_t operator()(const Person& p) const
	{
		return std::hash<int>()(p._age);
	}
};

struct PersonEqual
{
public:
	bool operator()(const Person& p1, const Person& p2) const
	{
		return p1._age == p2._age;
	}
};

int main()
{
	std::unordered_map<Person, int, PersonHash, PersonEqual> um;
	um.insert(std::make_pair<Person, int>(Person(1), 1));
	um.insert(std::make_pair<Person, int>(Person(2), 1));

	for (auto& e : um)
	{
		std::cout << e.first._age << " " << e.second << std::endl;
	}
	return 0;
}

​​​​​​​

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你可以使用 C++ 的 `unordered_map` 来存储定义类型。要在 `unordered_map` 使用自定义类型作为键或值,你需要提供一些额外的信息。 首先,你需要为你的自定义类型实现哈希函数。哈希函数将根据对象的内容生成一个哈希值,这个值将用于在 `unordered_map` 进行快速查找。你可以使用 `std::hash` 类型来生成哈希值,或者自己实现一个哈希函数。 接下来,你需要为你的自定义类型提供相等运算符(`operator==`)的实现。这是为了在 `unordered_map` 执行键的比较操作。 以下是一个示例,展示了如何在 `unordered_map` 存储定义类型 `Person`: ```cpp #include <iostream> #include <unordered_map> struct Person { std::string name; int age; bool operator==(const Person& other) const { return name == other.name && age == other.age; } }; // 自定义哈希函数 struct PersonHash { std::size_t operator()(const Person& person) const { std::size_t nameHash = std::hash<std::string>{}(person.name); std::size_t ageHash = std::hash<int>{}(person.age); return nameHash ^ ageHash; } }; int main() { std::unordered_map<Person, std::string, PersonHash> personMap; Person p1{"John", 25}; personMap[p1] = "Engineer"; Person p2{"Jane", 30}; personMap[p2] = "Manager"; // 输出值 std::cout << "Profession of John: " << personMap[p1] << std::endl; std::cout << "Profession of Jane: " << personMap[p2] << std::endl; return 0; } ``` 在此示例,我们定义了一个 `Person` 结构体,它包含一个 `name` 字符串和一个 `age` 整数。我们为 `Person` 实现了相等运算符并创建了一个自定义的哈希函数 `PersonHash`。 然后,我们创建了一个 `personMap`,它的键是 `Person` 类型,值是 `std::string` 类型。我们可以将 `Person` 对象作为键插入到 `personMap` ,并且可以使用键来访问对应的值。 请注意,在使用自定义类型作为 `unordered_map` 的键时,你需要提供自定义哈希函数和相等运算符的实现。这样才能正确地进行键的哈希和比较操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小唐学渣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值