如何在C++中创建一个用户定义类或结构的unordered_set?
C++中的unordered_set是一种高效的数据结构,它可以将任意类型的数据存储在哈希表中,并且具有快速的插入、查找和删除操作。在某些情况下,我们需要将自己定义的类或结构作为unordered_set的元素类型,但是使用起来不是那么简单。下面我们将介绍如何在C++中创建一个用户定义类型的unordered_set。
定义用户自定义类型
首先,我们需要定义一个用户自定义类型,这个类型可以是一个类或结构体。这里我们以一个简单的Person类为例:
class Person {
public:
std::string name;
int age;
bool operator ==(const Person& other) const{
return name == other.name && age == other.age;
}
};
namespace std {
template <>
struct hash<Person> {
std::size_t operator ()(const Person& person) const {
return std::hash<std::string>()(person.name) ^ std::hash<int>()(person.age);
}
};
}
这个Person类有两个字段,分别是姓名和年龄。为了让这个类能够作为unordered_set的元素类型,我们需要定义其相等性运算符(operator)和哈希函数(hash)。这里我们使用C++11中的特性来定义哈希函数,即为Person类型专门提供一个std::hash模板的特化实现。
创建unordered_set对象
定义好自定义类型之后,我们就可以开始创建unordered_set对象了。下面是一个简单的例子:
std::unordered_set<Person> persons;
persons.insert({"Alice", 20});
persons.insert({"Bob", 25});
for (const auto& person : persons) {
std::cout << person.name << " " << person.age << std::endl;
}
上面的代码创建了一个unordered_set对象,用于存储Person类型的元素。我们插入了两个Person对象,并遍历了整个unordered_set,输出其中每个Person对象的姓名和年龄。需要注意的是,我们可以直接使用花括号语法来构造和插入Person类型的元素。
自定义哈希函数
在上面的例子中,我们使用了C++11中的std::hash模板特化来为Person类型定义哈希函数。如果我们不想使用C++11中的哈希函数特化,也可以手动定义哈希函数,如下所示:
struct MyHash {
std::size_t operator ()(const Person& person) const {
std::size_t h1 = std::hash<std::string>()(person.name);
std::size_t h2 = std::hash<int>()(person.age);
return h1 ^ (h2 << 1);
}
};
std::unordered_set<Person, MyHash> persons;
上面的代码中,我们定义了一个名为MyHash的自定义哈希函数。该哈希函数和std::hash模板特化的实现相同,使用了两个std::hash调用来计算各自的哈希值,并将这些哈希值组合在一起得到最终的哈希值。在unordered_set的创建中,我们将自定义哈希函数作为第二个模板参数传递给它。
总结
C++中的unordered_set是一种高效的数据结构,可以将任意类型的数据存储在哈希表中,并具有快速的插入、查找和删除操作。如果我们想将自己定义的类或结构体作为unordered_set的元素类型,需要定义其相等性运算符和哈希函数。可以使用C++11中的std::hash模板特化来为自定义类型专门定义哈希函数,或者手动定义一个自定义哈希函数来计算其哈希值。