Middle
Τι πρέπει να κάνετε για να αποθηκεύσετε τη δομή σας σε unordered_map;
sobes.tech AI
Απάντηση από AI
Για να αποθηκεύσετε μια δομή ως κλειδί σε std::unordered_map, πρέπει να παρέχετε:
- Συνάρτηση κατακερματισμού (hash function): Βρίσκει την τιμή κατακερματισμού για το αντικείμενο της δομής.
- Τελεστή σύγκρισης ισότητας (
operator==): Συγκρίνει δύο αντικείμενα δομής για ισότητα.
Υπάρχουν διάφοροι τρόποι να παρέχετε αυτά τα στοιχεία:
-
Υπερφόρτωση του
operator==μέσα στη δομή και εξειδίκευση τουstd::hashγια τη δομή σας. Αυτή είναι η πιο συνηθισμένη και συστηνόμενη προσέγγιση.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; bool operator==(const MyStruct& other) const { return id == other.id && name == other.name; } }; // Εξειδίκευση του std::hash για το MyStruct namespace std { template <> struct hash<MyStruct> { size_t operator()(const MyStruct& obj) const { size_t h1 = hash<int>()(obj.id); size_t h2 = hash<std::string>()(obj.name); return h1 ^ (h2 << 1); } }; } // Παράδειγμα χρήσης στο main int main() { std::unordered_map<MyStruct, int> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; MyStruct key3 = {1, "Alice"}; // ισοδύναμο με το key1 my_map[key1] = 10; my_map[key2] = 20; if (my_map.count(key3)) { // my_map[key3] θα δώσει 10 } return 0; } -
Να παρέχετε τις συναρτήσεις κατακερματισμού και σύγκρισης ως ξεχωριστές παραμέτρους του προτύπου κατά την δήλωση του
unordered_map. Αυτό είναι λιγότερο βολικό αν χρησιμοποιείτε συχνά τη δομή ως κλειδί, καθώς πρέπει να δηλώνετε τους τύπους του συγκριτή και του κατακερματιστή σε κάθε δήλωση του κοντέινερ.#include <unordered_map> #include <string> #include <functional> struct MyStruct { int id; std::string name; }; // Ξεχωριστή συνάρτηση κατακερματισμού struct MyStructHash { size_t operator()(const MyStruct& obj) const { size_t h1 = std::hash<int>()(obj.id); size_t h2 = std::hash<std::string>()(obj.name); return h1 ^ (h2 << 1); } }; // Ξεχωριστή συνάρτηση σύγκρισης (ή functor) struct MyStructEqual { bool operator()(const MyStruct& lhs, const MyStruct& rhs) const { return lhs.id == rhs.id && lhs.name == rhs.name; } }; // Παράδειγμα χρήσης στο main int main() { std::unordered_map<MyStruct, int, MyStructHash, MyStructEqual> my_map; MyStruct key1 = {1, "Alice"}; MyStruct key2 = {2, "Bob"}; my_map[key1] = 10; my_map[key2] = 20; return 0; }
Σημαντικά σημεία:
- Ορθότητα της συνάρτησης κατακερματισμού: Για οποιαδήποτε δύο κλειδιά
aκαιb, ανa == b, τότεhash(a)πρέπει να είναι ίσο μεhash(b). Το αντίστροφο δεν απαιτείται (πιθανές συγκρούσεις). - Ποιότητα της συνάρτησης κατακερματισμού: Μια καλή συνάρτηση κατακερματισμού διανέμει ομοιόμορφα τις τιμές κατακερματισμού για διαφορετικά κλειδιά, ελαχιστοποιώντας τις συγκρούσεις και βελτιώνοντας την απόδοση (
O(1)κατά μέσο όρο). - Σταθερότητα: Οι τελεστές σύγκρισης και η συνάρτηση κατακερματισμού πρέπει να είναι
const, καθώς δεν πρέπει να τροποποιούν το αντικείμενο του κλειδιού.