Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision |
cpp:stl:container_common_functions [2020/05/29 11:01] – [Ανάθεση των περιεχομένων ενός container από τα περιεχόμενα οποιουδήποτε άλλου container] gthanos | cpp:stl:container_common_functions [2023/05/29 16:43] – [Εισαγωγή στοιχείου] gthanos |
---|
====== Κοινές συναρτήσεις για όλους τους containers ====== | ====== Κοινές συναρτήσεις για όλους τους containers ====== |
| |
==== Εισαγωγή στοιχείου ==== | ===== Εισαγωγή στοιχείου ===== |
| |
Με εξαίρεση την κλάση [[array|std::array]] που το μέγεθος των πινάκων που δημιουργεί είναι σταθερό και δηλώνεται κατά τη δήλωση του πίνακα, οι υπόλοιποι //containers// μπορούν να μεταβάλλουν το αριθμό των στοιχείων που αποθηκεύουν. Για την εισαγωγή ενός στοιχείου σε έναν //container// υπάρχουν οι συναρτήσεις //insert// για την εισαγωγή ενός αντιγράφου του στοιχείου στον container και //emplace// για την δημιουργία ενός αντικειμένου και εισαγωγή του στον //container//. Επιπλέον, μόνο για τους //sequence containers// η //insert// λαμβάνει ως πρώτο όρισμα έναν //iterator// που δηλώνει τη θέση εισαγωγής του στοιχείου στον container. Για τις υπόλοιπες κατηγορίες //containers//, η //insert// δεν λαμβάνει ως πρώτο όρισμα έναν //iterator//. Εάν λαμβάνει, αυτό είναι ενδεικτικό και καλό είναι να αποφεύγετε η χρήση του. | Με εξαίρεση την κλάση [[array|std::array]] που το μέγεθος των πινάκων που δημιουργεί είναι σταθερό και δηλώνεται κατά τη δήλωση του πίνακα, οι υπόλοιποι //containers// μπορούν να μεταβάλλουν το αριθμό των στοιχείων που αποθηκεύουν. Για την εισαγωγή ενός στοιχείου σε έναν //container// υπάρχουν οι συναρτήσεις //insert// για την εισαγωγή ενός αντιγράφου του στοιχείου στον container και //emplace// για την δημιουργία ενός αντικειμένου και εισαγωγή του στον //container//. Επιπλέον, μόνο για τους //sequence containers// η //insert// λαμβάνει ως πρώτο όρισμα έναν //iterator// που δηλώνει τη θέση εισαγωγής του στοιχείου στον container. Για τις υπόλοιπες κατηγορίες //containers//, η //insert// δε λαμβάνει ως πρώτο όρισμα έναν //iterator// (υπάρχουν περιπτώσεις που λαμβάνει, αλλά αυτό είναι ενδεικτικό και συνιστάται να αποφεύγετε τη χρήση του). |
| |
| <WRAP tip 80% center round> |
| Έχετε υπόψη σας ότι οποιοδήποτε αντικείμενο τοποθετήσετε μέσα σε ένα //container// θα δημιουργηθεί ένα αντίγραφο του συγκεκριμένου αντικειμένου μέσα στον //container//. Κατά συνέπεια, τα αντικείμενα που αποθηκεύονται είναι αντίγραφα των αντικειμένων που παρέχονται ως ορίσματα στις συνάρτηση εισαγωγής //insert// του //container//. |
| </WRAP> |
| |
Παραδείγματα: | Παραδείγματα: |
| |
=== A. Ένθεση σε λίστα === | ==== A. Ένθεση στους sequence_containers list, forward_list, vector και dequeue ==== |
| |
Σε ένα //sequence container// είναι υποχρεωτικό να προσδιορίσουμε τη θέση εισαγωγής του στοιχείου μέσω ενός //iterator// που παρέχεται ως πρώτο όρισμα στη συνάρτηση //insert//. | Σε ένα //sequence container// είναι υποχρεωτικό να προσδιορίσουμε τη θέση εισαγωγής του στοιχείου μέσω ενός //iterator// που παρέχεται ως πρώτο όρισμα στη συνάρτηση //insert//. |
</code> | </code> |
| |
=== Β. Ένθεση σε set === | <WRAP tip 80% center round> |
| Η διαφορά ανάμεσα στις μεθόδους //insert// και //emplace// είναι η εξής: |
| * Στη μέθοδο //insert// παρέχουμε ένα αντικείμενο και η μέθοδος κατασκευάζει ένα αντίγραφο του μέσω του κατασκευαστή αντιγραφέα (copy-constructor) της κλάσης //Student//. |
| * Στη μέθοδο //empace// παρέχουμε τα ορίσματα μέσω των οποίων κατασκευάζεται ένα αντικείμενο τύπου Student, μέσω του κατασκευαστή ''Student(const char *name, int aem);''. |
| </WRAP> |
| |
| ==== Β. Ένθεση σε set, unordered set ==== |
| |
Σε ένα //associative container// δεν μπορούμε να προσδιορίσουμε τη θέση εισαγωγής του στοιχείου σε αυτόν. Ως εκ τούτου η //insert// δεν λαμβάνει ως πρώτο όρισμα έναν //iterator//. | Σε ένα //associative container// δεν μπορούμε να προσδιορίσουμε τη θέση εισαγωγής του στοιχείου σε αυτόν. Ως εκ τούτου η //insert// δεν λαμβάνει ως πρώτο όρισμα έναν //iterator//. |
| |
<code cpp string_set_insert.cpp> | <code cpp student_set_insert.cpp> |
#include <iostream> // std::cout | #include <iostream> // std::cout |
#include <algorithm> // std::copy | #include <algorithm> // std::copy |
#include <set> // std::set | #include <set> // std::set |
#include <string> | #include "Student.hpp" |
| |
int main () { | int main () { |
std::string strings[] = { std::string("gamma"), std::string("beta"), std::string("delta") }; | Student students[] = { Student("Peter_Pan", 1234), Student("Tinker_Bell", 1235) }; |
| |
std::cerr << "----- Init set -----" << std::endl; | std::cerr << "----- Init set -----" << std::endl; |
std::set<std::string> myset; | std::set<Student> myset; |
for(int i=0; i<3; i++) | for(int i=0; i<2; i++) { |
myset.insert(strings[i]); | myset.insert(students[i]); // copy-constructor, insert first |
| myset.insert(students[i]); // copy-constructor, insert last |
| } |
| |
myset.emplace("alpha"); // argument construct, insert last | myset.emplace("Mickey_Mouse", 1237); // argument construct, insert last |
| |
std::cerr << "-------------------------\n"; | std::cerr << "-------------------------\n"; |
std::cerr << "myset contains:"; | std::cerr << "myset contains:"; |
for (std::set<std::string>::iterator it = myset.begin(); it!=myset.end(); it++) | for (std::set<Student>::iterator it = myset.begin(); it!=myset.end(); ++it) |
std::cerr << ' ' << *it; | std::cerr << ' ' << *it; |
std::cerr << std::endl; | std::cerr << std::endl; |
</code> | </code> |
| |
==== Διαγραφή στοιχείου ==== | ===== Διαγραφή στοιχείου ===== |
| |
Η διαγραφή στοιχείου είναι ανάλογη της εισαγωγής και γίνεται μέσω της συνάρτησης //erase//. H συνάρτηση επιστρέφει έναν //iterator// στο επόμενο στοιχείο από αυτό που έχει διεγραφεί. Για τους //sequence containers// σε αναλογία με την διαδικασία εισαγωγής, η συνάρτηση λαμβάνει ως όρισμα έναν //iterator// που δηλώνει τη θέση διαγραφής από τον container. Για τους //associative containers// η διαγραφή γίνεται παρέχοντας ως όρισμα τη θέση του κλειδιού (μέσω //iterator//) ή την τιμή του κλειδιού που επιθυμούμε να διαγράψουμε. | Η διαγραφή στοιχείου είναι ανάλογη της εισαγωγής και γίνεται μέσω της συνάρτησης //erase//. H συνάρτηση επιστρέφει έναν //iterator// στο επόμενο στοιχείο από αυτό που έχει διεγραφεί. Για τους //sequence containers// σε αναλογία με την διαδικασία εισαγωγής, η συνάρτηση λαμβάνει ως όρισμα έναν //iterator// που δηλώνει τη θέση διαγραφής από τον container. Για τους //associative containers// η διαγραφή γίνεται παρέχοντας ως όρισμα τη θέση του κλειδιού (μέσω //iterator//) ή την τιμή του κλειδιού που επιθυμούμε να διαγράψουμε. |
| |
=== A. Διαγραφή από λίστα === | ==== A. Διαγραφή από λίστα ==== |
| |
Το παρακάτω παράδειγμα είναι από τη σελίδα [[http://www.cplusplus.com/reference/list/list/erase/|http://cplusplus.com/list/erase]] | Το παρακάτω παράδειγμα είναι από τη σελίδα [[http://www.cplusplus.com/reference/list/list/erase/|http://cplusplus.com/list/erase]] |
| |
| |
=== B. Διαγραφή από set === | ==== B. Διαγραφή από set ==== |
| |
Το παρακάτω παράδειγμα είναι από τη σελίδα [[http://www.cplusplus.com/reference/set/erase/|http://cplusplus.com/set/erase]] | Το παρακάτω παράδειγμα είναι από τη σελίδα [[http://www.cplusplus.com/reference/set/erase/|http://cplusplus.com/set/erase]] |
</code> | </code> |
| |
==== Αναζήτηση στοιχείου ==== | ===== Αναζήτηση στοιχείου ===== |
| |
Η διαδικασία αναζήτησης ενός στοιχείου είναι διαφορετική εάν αναζητούμε σε //sequence container// ή σε //associative container//. | Η διαδικασία αναζήτησης ενός στοιχείου είναι διαφορετική εάν αναζητούμε σε //sequence container// ή σε //associative container//. |
| |
=== Αναζήτηση σε sequence container === | ==== Αναζήτηση σε sequence container ==== |
| |
H αναζήτηση σε sequence container γίνεται μέσω της συνάρτησης [[http://www.cplusplus.com/reference/algorithm/find/|std::find]]. Όπως θα δείτε και από τον ενδεικτικό κώδικα στο link η συνάρτηση λειτουργεί διατρέχοντας τον //container// με την βοήθεια ενός //iterator//. Το κόστος αναζήτησης είναι γραμμικό στο πλήθος των στοιχείων του //container// και για αυτό δεν αποτελεί βέλτιστη επιλογή για //associative// και //unordered associative containers//. Δείτε το παρακάτω ενδεικτικό παράδειγμα αναζήτησης σε μία λίστα. Η συνάρτηση [[http://www.cplusplus.com/reference/algorithm/find/|std::find]] επιστρέφει έναν //iterator// που δείχνει στην πρώτη θέση που εμφανίζεται το στοιχείο που αναζητούμε (μπορεί να εμφανίζεται σε περισσότερες θέσεις). Εάν δεν υπάρχει το στοιχείο που αναζητούμε η συνάρτηση //find// επιστρέφει έναν //iterator// που δείχνει στο σημείο του //container// που δείχνει και η συνάρτηση //end//. Το παρακάτω παράδειγμα είναι ενδεικτικό της χρήσης της //find//. | H αναζήτηση σε sequence container γίνεται μέσω της συνάρτησης [[http://www.cplusplus.com/reference/algorithm/find/|std::find]]. Όπως θα δείτε και από τον ενδεικτικό κώδικα στο link η συνάρτηση λειτουργεί διατρέχοντας τον //container// με την βοήθεια ενός //iterator//. Το κόστος αναζήτησης είναι γραμμικό στο πλήθος των στοιχείων του //container// και για αυτό δεν αποτελεί βέλτιστη επιλογή για //associative// και //unordered associative containers//. Δείτε το παρακάτω ενδεικτικό παράδειγμα αναζήτησης σε μία λίστα. Η συνάρτηση [[http://www.cplusplus.com/reference/algorithm/find/|std::find]] επιστρέφει έναν //iterator// που δείχνει στην πρώτη θέση που εμφανίζεται το στοιχείο που αναζητούμε (μπορεί να εμφανίζεται σε περισσότερες θέσεις). Εάν δεν υπάρχει το στοιχείο που αναζητούμε η συνάρτηση //find// επιστρέφει έναν //iterator// που δείχνει στο σημείο του //container// που δείχνει και η συνάρτηση //end//. Το παρακάτω παράδειγμα είναι ενδεικτικό της χρήσης της //find//. |
</code> | </code> |
| |
=== Αναζήτηση σε associative container και unordered associative container === | ==== Αναζήτηση σε associative container και unordered associative container ==== |
| |
Επειδή η συνάρτηση //find// ψάχνει γραμμικά μέσα στο περιεχόμενο του container δεν είναι βέλτιστή για containers που περιγράφονται από δέντρα ή από πίνακα κατακερματισμού. Αυτοί οι //containers// διαθέτουν δικές τους εξειδικευμένες συναρτήσεις //find// που ταιριάζουν στα χαρακτηριστικά της περιεχόμενης δομής που χρησιμοποιούν. | Επειδή η συνάρτηση //find// ψάχνει γραμμικά μέσα στο περιεχόμενο του container δεν είναι βέλτιστή για containers που περιγράφονται από δέντρα ή από πίνακα κατακερματισμού. Αυτοί οι //containers// διαθέτουν δικές τους εξειδικευμένες συναρτήσεις //find// που ταιριάζουν στα χαρακτηριστικά της περιεχόμενης δομής που χρησιμοποιούν. |
if(it != myset.end()) { | if(it != myset.end()) { |
myset.erase (it); | myset.erase (it); |
std::cout << "'buiscuits' erased\n"; | std::cout << "'biscuits' erased\n"; |
} | } |
else | else |
std::cout << "'buiscuits' not found\n"; | std::cout << "'biscuits' not found\n"; |
| |
print_set(myset); | print_set(myset); |
</WRAP> | </WRAP> |
| |
===== Ανάθεση των περιεχομένων ενός container από τα περιεχόμενα οποιουδήποτε άλλου container ===== | ===== Ανάθεση των περιεχομένων ενός container από τα περιεχόμενα ενός άλλου container ===== |
| |
Η ανάθεση των περιεχομένων ενός //container// από τα περιεχόμενα ενός άλλου //container// (δεν έχει σημασία ο τύπος) γίνεται μέσω της συνάρτησης //assign//. Παρακάτω δίνεται ένα παράδειγμα όπου αντιγράφονται τα περιεχόμενα ενός [[cpp:stl:array|std::array]] αντιγράφονται σε ένα [[cpp:stl:vector|std::vector]] με εξαίρεση το πρώτο και το τελευταίο στοιχείο του //array//. | Η ανάθεση των περιεχομένων ενός //container// από τα περιεχόμενα ενός άλλου //container// (δεν έχει σημασία ο τύπος) γίνεται μέσω της συνάρτησης //assign//. Παρακάτω δίνεται ένα παράδειγμα όπου αντιγράφονται τα περιεχόμενα ενός [[cpp:stl:array|std::array]] αντιγράφονται σε ένα [[cpp:stl:vector|std::vector]] με εξαίρεση το πρώτο και το τελευταίο στοιχείο του //array//. |
| |
int main () { | int main () { |
vector<int> v; | vector<int> v = {1,2,3}; |
array<int,6> a = {10, 20, 30, 40, 50, 60}; | array<int,6> a = {10, 20, 30, 40, 50, 60}; |
| |
v.assign(a.begin()+1, a.end()-1); | |
| |
| |
| /* Assigns 20, 30, 40, 50 |
| */ |
| v.assign(a.begin()+1, a.end()-1); // 10 20 30 40 50 60 |
| // ^ ^ |
| // begin()+1 end()-1 |
print(v); | print(v); |
} | } |
| |
<WRAP tip 80% center round> | <WRAP tip 80% center round> |
H συνάρτηση //assign// διαγράφει τα υφιστάμενα περιεχόμενα του //container// πριν ανάθεση των νέων περιεχομένων. Προσαρμόζει το μέγεθος του //container// ανάλογα με τον αριθμό των στοιχείων που θα εισάγει σε αυτόν. | H συνάρτηση //assign// διαγράφει τα υφιστάμενα περιεχόμενα του //container// πριν ανάθεση των νέων περιεχομένων. Επιπλέον, προσαρμόζει το μέγεθος του //container// ανάλογα με τον αριθμό των στοιχείων που θα εισάγει σε αυτόν. |
</WRAP> | </WRAP> |
| |
| |