rebecca93 Δημοσ. 8 Ιανουαρίου 2015 Δημοσ. 8 Ιανουαρίου 2015 Έχω δει και άλλα θέματα όπου συζητάνε αυτό το πρόβλημα αλλά δεν βλέπω να έχει δώσει κανείς κάποια πιο ολοκληρωμένη απάντηση. Μήπως μπορεί κάποιος να με βοηθήσει με τη κλάση garage/parking το οποίο θα γίνει με vector; Έχω αναβάσει τον κώδικα που έχω γράψει αλλά δεν νομίζω να είναι σωστό. Τα οχήματα που εισέρχονται στο πάρκινγκ υποτίθεται ότι είναι μόνο αυτοκίνητα κ δίκυκλα.Όταν εισέλθει ένα αυτοκίνητο,ακολουθείται η εξής διαδικασία:1.καταγράφονται τα στοιχεία:α.αριθμός κθκλοφορίαςβ.μάρκαγ.μοντέλοδ.χρώμαε.ώρα εισόδου2.ο υπάλληλος παρκάρει το αυτοκίνητο στην πρώτη ελεύθερη θέση3.όταν ο οδηγός αυτοκινήτου επιστρέψει ο υπάλληλος ρωτάει τον αριθμό αυτοκινήτου κ βρίσκει στο σύστημα το αυτοκίνητο.Καταγράφεται η ώρα εξόδου κ κόβεται απόδειξη πληρωμής.4.Ξεπαρκάρει το αυτοκίνητο κ αποχωρεί5.Στην περίπτωση του δικύκλου, η διαδικασία είναι η ίδια, με τη διαφορά πως ο ίδιος ο οδηγός του παρκάρει κ ξεπαρκάρει το δίκυκλο στη θέση που θα του υποδείξει ο υπάλληλος.Το σύστημα που θα υλοποιήσετε θα πρέπι να καλύπτει όλη την παραπάνω διαδικασία, λαμβάνοντας υπόψη τα ακόλουθα:-ο σταθμός διαθέτει 50 θέσεις αλλά πολλές φορές σταθμεύονται περισσότερα αυτοκίνητα σε χώρουσ μεταξύ των θέσεων (βραχυπρόθεσμα)-η χρέωση είναι 2 ευρώ η ώρα για αυτοκίνητα κ 0,5 ευρώ για δίκυκλα.}Επίσης ξέρουμε -ότι για την υλοπίηση των θέσεων έχουμε χρήση vector-τα αυτοκίνητα καταλαμβάνουν με τη σειρά τις θέσεις 1-50,αν όμως φύγει ενδιάμεσα π.χ. το πρώτο αυτοκίνητο,το επόμενο που θα εισέλθει θα μπει στη πρώτη θέση(η οποία θα έχει ελευθερωθεί πριν λίγο) parkingnew.zip
Moderators Kercyn Δημοσ. 9 Ιανουαρίου 2015 Moderators Δημοσ. 9 Ιανουαρίου 2015 Κατ' αρχάς αυτά που γράφεις είναι C++, όχι C. Στο λέω γιατί στον τίτλο έχεις βάλει C. Δεύτερον, τι πρόβλημα έχεις; Το έχεις τεστάρει; Τι δε δουλεύει; Το zip έχει 10 αρχεία μέσα. Πράγματα που μπορούν να διορθωθούν βλέπω, αλλά όχι λάθη του στυλ δε δουλεύει.
rebecca93 Δημοσ. 9 Ιανουαρίου 2015 Μέλος Δημοσ. 9 Ιανουαρίου 2015 Ναι όντως C++ είναι, μάλλον από τη βιασύνη μου έγραψα C. Ανέβασα και τα άλλα αρχεία επειδή δεν έχω βάλει ακόμα σχόλια και δεν ήξερα αν κάποιος θα καταλάβαινε τι θέλω να κάνω στο garage χωρίς να τα δει και τα άλλα. Είμαι σίγουρη πως το πρόβλημα μου είναι στο garage πάντως. Δεν έχω καταλάβει και πολύ καλά τους vectors και όποια βοήθεια μπορεί να μου δώσει κανείς είτε διορθώσουν τον κώδικα ή να μου εξηγήσουν τι δεν έχω κάνει και πολύ σωστό να το διορθώσω μόνη μου.
Moderators Kercyn Δημοσ. 9 Ιανουαρίου 2015 Moderators Δημοσ. 9 Ιανουαρίου 2015 Κοιτάζοντας μόνο τα αρχεία Garage.h και Garage.cpp, έχω μερικές παρατηρήσεις: Κατ' αρχάς μη χρησιμοποιείς ποτέ using σε header files. Ένα παράδειγμα του γιατί να μην το κάνεις μπορείς να δεις εδώ. Δεύτερον, ορίζεις virtual destructor στο Garage. Virtual destructor θες συνήθως σε μία base class την οποία θα κάνουν inherit άλλες κλάσεις, για να αποφύγεις memory leaks (ορίζοντας virtual destructor δε σε προστατεύει αυτόματα από leaks, είναι όμως απαραίτητη προϋπόθεση στην derived class έχεις πράγματα που χρειάζεται να καταστραφούν). Περισσότερα εδώ. Τρίτον, πριν πάμε στην επίμαχη addVehicle. Ορίζεις ένα attribute garage ως vector<Vehicle*>* garage. Ο pointer στον vector είναι αχρείαστος. Θα μπορούσες να ορίσεις το garage ως std::vector<Vehicle *>. Ο vector, όπως και πολλές άλλες κλάσεις της STL είναι copy-constructible, δηλαδή μπορείς να φτιάξεις ένα vector ως αντίγραφο ενός άλλου vector παιρνόντας τον απλώς ως όρισμα. Δε χρειάζεται να μεταφέρεις pointers δεξιά κι αριστερά. Πηγαίνοντας τώρα στην addVehicle, δεν ξέρω πώς την καλείς αλλά η υλοποίηση δε μου φαίνεται σωστή. Θα μπορούσες να την υλοποιήσεις πολύ πολύ πιο απλά: void Garage::addVehicle(Vehicle *v) { garage.push_back(v); } Τώρα, η addVehicle δέχεται ένα Vehicle * και το προσθέτει στο τέλος garage. Τώρα για την deleteVehicle. Απ' ό,τι καταλαβαίνω δίνεις την πινακίδα και βγάζεις το αυτοκίνητο απ' το garage. Δεν υπάρχει λόγος η πινακίδα να περνάει ως reference, μιας και το std::string είναι copy-constructible (και δεν το πειράζεις μέσα στη συνάρτηση). Απλούστερα, αυτό που γράφεις μπορεί να γραφεί κι έτσι: for (auto it = garage.begin(); it != garage.end(); it++) { if (it->lp == lp) { garage.erase(it); break; } } Όπως βλέπεις, αντί να γράφω όλο το μακρυνάρι με τον iterator, γράφω μόνο ένα auto. Το auto κάνει την μεταβλητή μου να έχει τον ίδιο τύπο με αυτό που επιστρέφει η garage.begin, δηλαδή std::vector<Vehicle *>::iterator. Αν, πχ, γράψω αυτό auto a = 5; τότε το a είναι integer, μιας και το 5 είναι integer. Αν σε μπερδεύει μπορείς να γράφεις όλο τον τύπο και να αφήσεις το auto. Μπορείς, όμως, και να μη χρησιμοποιήσεις καθόλου for. Αντί γι' αυτό, μπορείς να χρησιμοποιήσεις το erase-remove idiom. Αυτό είναι πιο προχωρημένο και το βάζω μόνο για να δεις και κάτι καινούριο αν σ' ενδιαφέρει. garage.erase(std::remove_if(std::begin(garage), std::end(garage), [lp](const Vehicle *v){ return v->lp == lp; }), std::end(garage)); Αυτή η γραμμή θα διατρέξει όλο το vector garage και θα διαγράψει κάθε στοιχείο (δηλαδή Vehicle *) του οποίου η πινακίδα είναι ίδια με την παράμετρο που δώθηκε στη συνάρτηση. Αυτό το περίεργο [lp](const Vehicle *v){ return v->lp == lp; } λέγεται lambda function και μπορείς να το σκεφτείς ως εξής (το όνομα είναι ενδεικτικό): bool checkLicencePlate(const Vehicle *v, std::string lp) { return v->lp == lp; } Δε βρήκα τρόπο να γλυτώσω τη lambda στο erase-remove, αν κάποιος άλλος ξέρει πώς ας το γράψει. Προχωρώντας στην findVehicle, μπορεί κι αυτή να απλοποιηθεί, θα σταθώ πρώτα στη γραμμή cout<<*it<<endl; Αυτό που έχεις εσύ στο μυαλό σου, δηλαδή να εκτυπώσει τη θέση του αυτοκινήτου, είναι διαφορετικό απ' αυτό που του λες. Εσύ του λες να εκτυπώσει τον iterator που πληροί τις προϋποθέσεις (δηλαδή οι πινακίδες που έδωσες ταιριάζουν με τις πινακίδες του οχήματος που δείχνει ο iterator). Αν θες να εκτυπώσεις τη θέση (index) του iterator μέσα στο vector, μπορείς να κάνεις αυτό: std::cout << it - garage.begin() << std::endl; Δηλαδή η συνάρτησή σου γίνεται έτσι: void Garage::findVehicle(string lp) { for (auto it = garage.begin(); it != garage.end(); it++) { if ((*it)->lp == lp) { std::cout << lp << std::endl; std::cout << "The vehicle is parked in space: " << (it - garage.begin()) << std::endl; } } } Τελειώνοντας, στο destructor σου κάνεις empty το garage και στη συνέχεια κάνεις delete. Το delete δεν είναι απαραίτητο, μιας και το garage δεν είναι πια pointer. Το empty επίσης δεν είναι απαραίτητο. Το vector έχει κι αυτό destructor ο οποίος θα εκτελεστεί μόλις το Garage object σου φύγει εκτός scope, οπότε δε χρειάζεται ν' ανησυχείς για το καθάρισμά του. Επίσης έχεις κι έναν assignment operator τον οποίον δεν υλοποιείς. Υ.Γ.: Αν έχεις όρεξη ρίξε μια ματιά κι εδώ. 3
rebecca93 Δημοσ. 9 Ιανουαρίου 2015 Μέλος Δημοσ. 9 Ιανουαρίου 2015 Ευχαριστώ πάρα πολύ για όλη τη βοήθεια. Θα προσπαθήσω να κάνω τις αλλαγές που μου είπες, έχω μια απορία αν γράψω αυτό: void Garage::addVehicle(Vehicle *v){ garage.push_back(v);} θα βάλει το αμάξι στο τέλος έτσι; το πρόβλημα μου είναι ότι πρέπει να μπει στη πρώτη κενή θέση..πρέπει να ψάξω για κάποιο null;
Moderators Kercyn Δημοσ. 9 Ιανουαρίου 2015 Moderators Δημοσ. 9 Ιανουαρίου 2015 Όταν αφαιρείς ένα αντικείμενο απ' το vector τότε τα στοιχεία του vector θα ανακατανεμηθούν, έτσι ώστε να καλύψουν τη θέση του αντικειμένου που διεγράφη. Αν θες να έχεις συγκεκριμένες fixed θέσεις και τα αντικείμενα (οχήματα) να μην αλλάζουν θέση, τότε πρέπει να χρησιμοποιήσεις άλλον container. Κάτι που μου έρχεται τελείως πρόχειρα στο μυαλό είναι να έχεις έναν std::vector από std::pair. Η πρώτη τιμή του pair θα είναι μία boolean που θα δηλώνει αν η θέση είναι κενή ή όχι. Η δεύτερη ένα Vehicle * το οποίο θα κρατάει το παρκαρισμένο όχημα αν η θέση είναι πιασμένη ή θα έχει ένα nullptr αν είναι κενή. Τώρα βέβαια μπορεί να υπάρχει και πιο εύκολος τρόπος αλλά αυτή τη στιγμή αυτό μου έρχεται στο μυαλό.
defacer Δημοσ. 10 Ιανουαρίου 2015 Δημοσ. 10 Ιανουαρίου 2015 std::array Άκυρο, ξαναδιάβασα την εκφώνηση. Πάντως είναι γεγονός ότι για κάτι που έχει πάντα συγκεκριμένο μέγεθος (parking) το (resizable) vector δε βγάζει νόημα.
rebecca93 Δημοσ. 10 Ιανουαρίου 2015 Μέλος Δημοσ. 10 Ιανουαρίου 2015 Νόμιζα ότι εγώ δεν είχα καταλάβει σωστά τους vector αλλά αφού λέτε και εσείς ότι δεν βγάζει νόημα να το χρησιμοποιούμε... δεν ξέρω γιατι μας είπε ο καθηγητής να το κάνουμε έτσι..
παπι Δημοσ. 10 Ιανουαρίου 2015 Δημοσ. 10 Ιανουαρίου 2015 Νόμιζα ότι εγώ δεν είχα καταλάβει σωστά τους vector αλλά αφού λέτε και εσείς ότι δεν βγάζει νόημα να το χρησιμοποιούμε... δεν ξέρω γιατι μας είπε ο καθηγητής να το κάνουμε έτσι.. Λογικα περιμενει εναν vector που εχει 50 parking. Κατι το οποιο δεν εχεις, εφοσον το parking για σενα ειναι ειτε null ptr ειτε καποιο οχημα.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα