====== std::map και std::multimap ======
Ένα [[http://www.cplusplus.com/reference/map/map/|std::map]] αποτελεί ένα σύνολο μοναδικών στοιχείων, όπου κάθε τέτοιο στοιχείο αποτελεί κλειδί για την εύρεση-αντιστοίχιση με ένα άλλο αντικείμενο που ονομάζουμε "τιμή" (//value//). Κάθε κλειδί προσδιορίζει μοναδικά μία "τιμή", η οποία δεν είναι απαραίτητο να είναι μοναδική (οι τιμές μπορεί να επαναλαμβάνονται).
Τα στοιχεία-κλειδιά αποθηκεύονται εσωτερικά σε ένα ισοζυγισμένο δέντρο αναζητήσεως (π.χ.[[wp>Red–black_tree]], [[wp>AVL_tree]]), όπως ακριβώς και στο [[cpp:stl:set|std::set]].
Η κατάταξη ενός νέου στοιχείου-κλειδιού γίνεται πάντα μέσω σύγκρισης με τα υπόλοιπα στοιχεία που είναι αποθηκευμένα στην δομή. Για τον λόγο αυτό, απαραίτητη προϋπόθεση για τη λειτουργία του //map// (όπως και στο [[cpp:stl:set|std::set]]) είναι για τον τύπο του κλειδιού να παρέχονται ο τελεστής σύγκρισης %%<%%. Δύο κλειδιά ιδίου τύπου θεωρούνται ίσα σε ένα //map// εάν η παρακάτω λογική έκφραση είναι αληθής.
if(!(a < b) && !(b < a))
Ένα [[http://www.cplusplus.com/reference/map/multimap/|std::multimap]] αποτελεί ένα σύνολο από όχι απαραίτητα μοναδικά κλειδιά, τα οποία είναι αποθηκευμένα σε ένα ισοζυγισμένο δέντρο αναζητήσεως (όπως το //map//). Ο τρόπος σύγκρισης και η κατάταξη των στοιχείων είναι όμοια με την επίπλέον σημείωση ότι το δέντρο επιτρέπει την εμφάνιση ενός κλειδιού περισσότερες από μία φορές.
Στα παρακάτω σχήματα διακρίνεται η δομή ενός [[http://www.cplusplus.com/reference/map/map|std::map]] και ενός [[http://www.cplusplus.com/reference/map/multimap/|std::multimap]], όπου τα κλειδιά είναι ακέραιοι και οι τιμές είναι αντικείμενα τύπου //std::string//.
| {{ :cpp:stl:map01.png? |}}| {{ :cpp:stl:multimap01.png? |}} |
| **Σχήμα 1. std::map** | **Σχήμα 2. std::multimap** |
===== Επίδοσης της δομής =====
Η επίδοση της δομής είναι ανάλογη των δομών [[cpp:stl:set|std::set και std::multiset]] λαμβάνοντας υπόψη τα στοιχεία-κλειδιά των //std::map// και //std::multimap//.
===== Η κλάση std::pair =====
Προκειμένου να μπορέσει να υπάρξει η αντιστοίχιση μεταξύ στοιχείου-κλειδιού και στοιχείου-τιμής τα δεδομένα σε ένα [[http://www.cplusplus.com/reference/map/map/|std::map]] αντιστοιχίζονται σε ζευγάρια. Η //templated// κλάση της //STL// που υποστηρίζει την αποθήκευση ζευγών δεδομένων είναι η κλάση [[http://www.cplusplus.com/reference/utility/pair/|std::pair]]. Η κλάση μπορεί να αποθηκεύσει δύο αντικείμενα ίδιου ή διαφορετικού τύπου. Στο παράδειγμα που ακολουθεί δημιουργούμε δύο αντικείμενο της κλάσης //std::pair// και προσπελαύνουμε τα στοιχεία τους μέσω των public πεδίων της κλάσης [[http://www.cplusplus.com/reference/utility/pair/|std::pair]] **first** και **second**.
#include
#include
#include
#include
#include "Student.hpp"
int main() {
std::pair peter_pan(
Student("Peter Pan", 1234),
std::string("Wendy House, Neverland")
);
std::pair mickey_mouse = make_pair(
Student("Mickey Mouse", 1235),
std::string("Walt Disney World Communications, P.O Box 10040, Lake Buena Vista, Florida 32830-0040 ")
);
std::cout << peter_pan.first << " -> " << peter_pan.second << std::endl;
std::cout << mickey_mouse.first << " -> " << mickey_mouse.second << std::endl;
}
Εκτός από τον κατασκευαστή της κλάσης [[http://www.cplusplus.com/reference/utility/pair/|std::pair]] υπάρχει και η συνάρτηση [[http://www.cplusplus.com/reference/utility/make_pair/|std::make_pair]], η οποία κατασκευάζει και επιστρέφει ένα αντικείμενο τύπου [[http://www.cplusplus.com/reference/utility/pair/|std::pair]] με βάση τα ορίσματα που λαμβάνει.
===== Ένθεση και διάτρεξη ενός std::map ή std::multimap =====
#include
Παρατηρήσεις:
* Τα στοιχεία εκτυπώνονται σε αύξουσα σειρά με βάση το κλειδί κάθε εγγραφής.
* Η συνάρτηση //emplace// σε ένα //std::map// κατασκεύαζει το αντικείμενο τύπου //std::pair// και όχι το κλειδί ή τιμή που αντιστοιχεί στο κλειδί.
Αλλάξτε την κλάση //std::map// σε //std::multimap// και παρατηρήστε τις αλλαγές στην εκτύπωση.
===== Οι συναρτήσεις operator[] και at =====
==== H συνάρτηση operator[] ====
Η συνάρτηση [[http://www.cplusplus.com/reference/map/map/operator[]| operator[] ]] έχει διπλό ρόλο //α)// να επιστρέψει την τιμή ενός κλειδιού που είναι αποθηκευμένο στο //std::map// ή //std::multimap// και //β)// να θέσει την τιμή ενός κλειδιού που είναι ή δεν είναι αποθηκευμένο sto //std::map//, //std::multimap//.
=== Παράδειγμα 1ο - Ανάγνωση με χρήση του operator [] ===
#include
=== Παράδειγμα 2ο - Εγγραφή με χρήση του operator [] ===
#include
==== H συνάρτηση at ====
Η συνάρτηση [[http://www.cplusplus.com/reference/map/map/at| at ]] έχει ανάλογο ρόλο με τη συνάρτηση [[http://www.cplusplus.com/reference/map/map/operator[]| operator[] ]], δηλαδή μπορεί να διαβάσει ή να θέσει την τιμή ενός κλειδιού στο //std::map//. Η διαφορά της συγκεκριμένης συνάρτησης σε σχέση με την [[http://www.cplusplus.com/reference/map/map/operator[]| operator[] ]] είναι ότι εάν το κλειδί δεν υπάρχει στο //std::map// παράγει ένα //exception// του τύπου [[http://www.cplusplus.com/reference/stdexcept/out_of_range/|std::out_of_range]] .
=== Παράδειγμα 1ο - Ανάγνωση με χρήση της συνάρτησης at ===
#include
=== Παράδειγμα 2ο - Εγγραφή με χρήση της συνάρτησης at ===
#include
===== Οι συναρτήσεις lower_bound, upper_bound και equal_range =====
Οι συναρτήσεις [[cpp:stl:set#%CE%BF%CE%B9_%CF%83%CF%85%CE%BD%CE%B1%CF%81%CF%84%CE%AE%CF%83%CE%B5%CE%B9%CF%82_lower_bound_upper_bound_%CE%BA%CE%B1%CE%B9_equal_range|lower_bound, upper_bound και equal_range]] υπάρχουν και για τις κλάσεις [[cpp:stl:map| std::map και std::multimap]]. Η λογική των συναρτήσεων αυτών είναι όμοια με το [[cpp:stl:set|std::set]] με την διαφορά ότι η αναζήτηση γίνεται στα κλειδιά του //std::map//. Το παρακάτω παράδειγμα είναι από την σελίδα [[http://www.cplusplus.com/reference/map/map/lower_bound/|cplusplus.com]].
// map::lower_bound/upper_bound
#include
#include