C++程序設計:自定義類做爲Key的unordered_map編程技法

自定義類做爲Key的unordered_map編程技法

如何用自定義類型做爲unordered_map的key呢?

在上一節,咱們講到:這是自定義類型做爲map的Key的編程技法與原理。咱們這裏先只談技法,原理下次講哈希表再去探討。ios

分析做爲unordered_map的Key的條件

聯想標記數組算法,其實標記數組就是一種哈希,只是那是一種如下標(非負整型做爲Key)的哈希表。unordered_map的底層實現就是哈希表實現的,這個能夠聯想類比標記數組!算法

回顧標記數組的作法!在得到標記下標的時候,也就是知道Key的時候,咱們要對數組中同爲Key下標的數組元素進行操做。其實哈希表也差很少的,那麼你們思考,什麼樣的類才能知足這個操做呢?編程

首先,須要到數組中查找是否已經標記了這個元素,若是沒有加上標記,若是有就對標記的值(也就是Key-Value的Value)進行訪問。那麼,咱們的類就須要可以支持找到相同Key的方法,也就是「判等」方法,這經過重載運算符==實現!其實和Java的重寫equal和hashcode方法差很少。數組

光有判等方法不夠,爲了提升效率,咱們能夠先採用哈希算法,獲得對應的哈希值。若是哈希值相同再判等,爲何這樣呢?是爲了不哈希碰撞!bash

實例編程技法

仍是上一篇博客的例子:ide

給定N個學生,用unordered_map存儲,而且給學生成績進行打分。實現的程序是:函數

#include <iostream>
#include <unordered_map>
#include <algorithm>
using namespace std;

class Student {
    friend ostream& operator<<(ostream& out, const Student& res);
private:
    string name;
    int score;
public:
    Student(string name_, int score_) : name(name_), score(score_) {

    }

    bool operator==(const Student& obj) const {
        return name == obj.name && score == obj.score;
    }

    string getName() const {
        return name;
    }

    int getScore() const {
        return score;
    }
};

ostream& operator<<(ostream& out, const Student& res) {
    out << "Name : " << res.name << ",\tscore : " << res.score;
    return out;
}

class hashFunctor {
public:
    size_t operator()(const Student& obj) const {
        return hash<string>()(obj.getName()) ^ hash<int>()(obj.getScore());
    }
};

char getRank(int score) {
    if (score >= 90)
        return 'A';
    else if (score >= 60)
        return 'B';
    else
        return 'C';
}

int main() {
    unordered_map<Student, char, hashFunctor> umpStu;
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        string curName;
        int curScore;
        cin >> curName >> curScore;
        umpStu[Student(curName, curScore)] = getRank(curScore);
    }
    for (auto it : umpStu) {
        cout << it.first << "\trank : " << it.second << endl;
    }
    return 0;
}

輸出結果是:spa

Name : jiangjy, score : 98      rank : A
Name : zhangwj, score : 67      rank : B
Name : zuozy,   score : 98      rank : A
Name : lifl,    score : 86      rank : B
Name : jiangzl, score : 48      rank : C

你們能夠看到,這裏是無序的狀態了!因此unordered_map又叫無序關聯容器。code

編程技法總結

(一)自定義類型做爲map的Key對象

須要重載小於運算符

(二)自定義類型做爲unordered_map的Key

須要重載==運算符

須要一個仿函數(只重載函數調用運算符() 的類)做爲參數構造unordered_map對象

相關文章
相關標籤/搜索