在C++ STL中使用unordered_set hash_function()

在C++ STL中使用unordered_set hash_function()

unordered_set是C++ STL中的一个容器,它通过哈希表实现快速查找、插入、删除元素的操作。而哈希表的实现离不开哈希函数,它是将数据映射到哈希表中的关键步骤。在C++11中,我们可以通过重载哈希函数的方式来定义我们自己的哈希函数,以适应不同类型的数据。

unordered_set简介

unordered_set是一个关联容器,它用哈希表实现存储和查找元素。无序容器的优点是查询效率高,而缺点是元素没有顺序性。对于unordered_set,可以用下面的方式定义:

#include<unordered_set>
unordered_set<int> mySet;

这样就定义了一个名为mySet的unordered_set容器,它存储的元素类型为int型。

哈希函数

由于unordered_set的实现是通过哈希表来存储元素的,所以哈希函数是我们需要自定义的关键部分。在C++11之前,我们必须手动实现哈希函数并将其作为unordered_set容器类的模板参数之一。在C++11中,我们可以通过对类std::hash进行特化实现自己的哈希函数。

下面的示例演示如何为一个自定义的类型Person实现哈希函数:

#include<iostream>
#include<unordered_set>

using namespace std;

class Person {
public:
    string name;
    int age;
    int id;
};

namespace std {
    template<>
    struct hash<Person> {
        size_t operator()(const Person& p) const {
            return hash<string>()(p.name) ^ hash<int>()(p.age) ^ hash<int>()(p.id);
        }
    };
}

int main() {
    unordered_set<Person> personSet;
    Person p1 = { "Lucy", 25, 123 };
    Person p2 = { "Tom", 30, 456 };
    Person p3 = { "Lucy", 25, 789 };
    personSet.insert(p1);
    personSet.insert(p2);
    personSet.insert(p3);
    cout << personSet.size() << endl; //输出2,p1和p3被认为是同一个元素
    system("pause");
    return 0;
}

在这个例子中,我们重载了std::hash<>,该结构体有一个用于计算哈希值的模板函数operator()。Person是我们自定义的结构体类型,它有三个成员变量:name、age和id。具体来说,它通过三个哈希函数将string类型的name、int类型的age和id顺序地组合起来,产生一个哈希值。这就是哈希函数的工作原理。

注意,我们必须将重载过的哈希函数置于标准命名空间std中,以便unordered_set容器能够正确找到它。

自定义类型

我们可以使用C++ STL中已有的类型,比如string、int、double等等。但是如果我们定义的类型并不是这些基本类型,我们需要通过对std::hash<>进行特化的方式来实现我们自己的哈希函数。

下面的示例演示了如何为自定义类Student实现哈希函数:

#include<iostream>
#include<unordered_set>

using namespace std;

class Student {
public:
    string name;
    int age;
    int id;
    bool operator==(const Student& s) const {
        return name == s.name && age == s.age && id == s.id;
    }
};

namespace std {
    template<>
    struct hash<Student> {
        size_t operator()(const Student& s) const {
            return hash<string>()(s.name) ^ hash<int>()(s.age) ^ hash<int>()(s.id);
        }
    };
}

int main() {
    unordered_set<Student> studentSet;
    Student s1 = { "Lucy", 25, 123 };
    Student s2 = { "Tom", 30, 456 };
    Student s3 = { "Lucy", 25, 789 };
    studentSet.insert(s1);
    studentSet.insert(s2);
    studentSet.insert(s3);
    cout << studentSet.size() << endl; //输出2,s1和s3被认为是同一个元素
    system("pause");
    return 0;
}

在这个例子中,我们定义了一个自定义的类Student,它有三个成员变量:name、age和id。为了判断两个Student对象是否相等,我们还重载了运算符。接下来,我们为这个类实现了一个哈希函数,它和前面我们为Person类实现的哈希函数非常类似。

结论

C++ STL的unordered_set容器采用哈希表来实现存储和查找元素。为了实现哈希表,我们需要自定义哈希函数。在C++11中,你可以通过对std::hash进行特化实现哈希函数。为了实现哈希函数,你需要选择一些关键的哈希函数,比如std::hash<std::string>、std::hash<int>等等,对每个成员变量分别计算哈希值并将其组合。这使得你可以使用unordered_set来存储自定义的类型,比如Person、Student等。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程

C++ 教程