petran91 Δημοσ. 30 Μαΐου 2015 Δημοσ. 30 Μαΐου 2015 (επεξεργασμένο) Καλησπέρα σας, έχω να παραδώσω μία άσκηση και χρειάζομαι τα φώτα σας. Η άσκηση είναι αυτή:https://www.dropbox.com/s/hk3se9qqv3qm22d/20150530_203115.jpg?dl=0 Για το πρώτο ερώτημα έχω γράψει αυτό: void an(int N){ //prwto erwtima std::list<int> a1; int count=0; int k=N; int tp=N; int pt=N; while (k!=0){ k=k/10; count=count+1; } //std::cout<<count; - dokimi an douleuei i while std::list<int>::iterator it1=a1.begin(); for (int i=1;i<=count;i++){ tp=pt%10; pt=pt/10; a1.push_front(tp);} int z=a1.size(); // std::cout<<z;// -dokimi an ftiaxtike i lista return ;} Το οποίο κάνει τη δουλειά. Για το δεύτερο ερώτημα όμως χρειάζομαι function η οποία θα δέχεται στα ορίσματα της iterators.Δεν γνωρίζω πώς να το κάνω αυτό, ούτε πώς να κάνω μια function να γυρίζει πίσω λίστα. Και αυτό το χρειάζομαι ώστε να δίνω έναν αριθμό στην main, να τον αναλύει η an, και στη συνέχεια να παίρνει τις λίστες μια τρίτη συνάρτηση και να κάνει την πρόσθεση και να επιστρέφει iterator της τρίτης λίστας, η την τρίτη λίστα ολόκληρη.Μπορείτε να με βοηθήσετε σε αυτό?Ευχαριστώ εκ των προτέρων. Υ.Γ Είμαι πολύ αρχάριος στη γλώσσα οπότε όσο πιο απλά γίνεται σας παρακαλώ οι απαντήσεις σας EDIT: Την βρήκα την άκρη μετά από ώρες ταλαιπωρίας... Έχω segmentation fault βέβαια για το β ερώτημα αλλά θα βρεθεί άκρη ελπίζω Επεξ/σία 30 Μαΐου 2015 από petran91
Moderators Kercyn Δημοσ. 31 Μαΐου 2015 Moderators Δημοσ. 31 Μαΐου 2015 Πώς κατάφερες να πάρεις segfault στη C++;
petran91 Δημοσ. 31 Μαΐου 2015 Μέλος Δημοσ. 31 Μαΐου 2015 Βγαίνω εκτός λίστας λογικά. Δεν το έχω διορθώσει ακόμα.Παραθέτω τον κώδικα για όποιον θέλει να το δει. Η προβληματική συνάρτηση είναι η τελευταία.(έχω πράγματα που δεν χρειάζονται μέσα, απλά τα είχα επειδή έκανα δοκιμές). #include <iostream> #include <list> std::list<int> an(int N); std::list<int>::iterator athr(std::list<int>::iterator Abeg,std::list<int>::iterator Aend, std::list<int>::iterator Bbeg,std::list<int>::iterator Bend,std::list<int>::iterator Cbeg); std::list<int> an(int N,std::list<int> a11){ //prwto erwtima; int count=0; int k=N; int tp=N; int pt=N; while (k!=0){ k=k/10; count=count+1; } //std::cout<<count; - dokimi an douleuei i while std::list<int>::iterator it1=a11.begin(); for (int i=1;i<=count;i++){ tp=pt%10; pt=pt/10; a11.push_front(tp);} int z=a11.size(); // std::cout<<z;// -dokimi an ftiaxtike i lista return a11;} int main(){ int N1=1958723584; int N2=60945983; std::list<int> a111; std::list<int> a222; std::list<int> a11; std::list<int> a22; std::list<int> a3; std::list<int>::iterator abeg=a111.begin(); std::list<int>::iterator aend=a111.end(); std::list<int>::iterator bbeg=a222.begin(); std::list<int>::iterator bend=a222.end(); std::list<int>::iterator cbeg=a3.begin(); a111=an(N1,a11); // prwto erwtima a222=an(N2,a22); cbeg=athr(a111.begin(),a111.end(),a222.begin(),a222.end(),a3.begin()); //std::cout<<a11.size();//-dokimi an gurnaei ti lista swsta. for (std::list<int>::iterator it=a3.end();it!=a3.begin();it--){ //deytero erwtima ektypwnei to apotelesma std::cout<<*it;} // std::cout<<a111.size()<<'\n'; //std::cout<<a222.size(); //std::cout<<*a33; return 0;} std::list<int>::iterator athr(std::list<int>::iterator Abeg,std::list<int>::iterator Aend, std::list<int>::iterator Bbeg,std::list<int>::iterator Bend,std::list<int>::iterator Cbeg){ while (Abeg!=Aend || Bbeg!=Bend){ int c=0; //deiktis gia to an paei panw apo 10 to a8roisma if ((*Aend+*Bend+c)<10){ *Cbeg=*Aend+*Bend+c; c=0;} if ((*Aend=*Bend+c)>9){ *Cbeg=(*Aend+*Bend+c)%10; c=1;} *Aend=0; *Bend=0; if (Abeg!=Aend){ Aend--;} if (Bbeg!=Bend){ Bend--;} Cbeg++;} return Cbeg;}
Moderators Kercyn Δημοσ. 31 Μαΐου 2015 Moderators Δημοσ. 31 Μαΐου 2015 Είναι λίγο δυσανάγνωστο αυτό που έχει γράψει, ειδικά στη 2η συνάρτησή σου. Αυτά έγραψα εγώ Αριθμός -> Λίστα std::list<int> IntToList(int Number) { if (Number < 0) { return std::list<int>(); } std::list<int> ReturnList = std::list<int>(); std::string NumBuffer = std::to_string(Number); for (auto c : NumBuffer) { // This will only work if we're using ASCII and will most likely break if another encoding is used. int NumberToAdd = c - '0'; ReturnList.push_back(NumberToAdd); } return ReturnList; } Βάζω τα ψηφία του αριθμού σε ένα string και στη συνέχεια παίρνω το κάθε ψηφίο, το μετατρέπω από char σε int και το βάζω σε μια λίστα. Η for αυτή λέγεται range-based for και είναι ιδιαίτερα χρήσιμη σε περιπτώσεις με iterators. Εσύ το χειρίστηκες με αριθμητικό τρόπο, που φυσικά δεν είναι λάθος, απλώς είναι ένας άλλος τρόπος να γίνει το ίδιο πράγμα. Πρόσθεση λιστών std::list<int> AddNumberLists(std::list<int> FirstList, std::list<int> SecondList) { std::list<int> ReturnList = std::list<int>(); int Carry = 0; FirstList.reverse(); SecondList.reverse(); // If the lists are of different size, add 0s to the shorter list to make them even. if (FirstList.size() > SecondList.size()) { for (int i = 0; i <= (FirstList.size() - SecondList.size()); i++) { SecondList.push_back(0); } } else if (FirstList.size() < SecondList.size()) { for (int i = 0; i <= (SecondList.size() - FirstList.size()); i++) { FirstList.push_back(0); } } auto FirstIter = FirstList.begin(); auto SecondIter = SecondList.begin(); for (; (FirstIter != FirstList.end()) && (SecondIter != SecondList.end()); FirstIter++, SecondIter++) { int Sum = *FirstIter + *SecondIter + Carry; if (Sum > 9) { Carry = 1; Sum -= 10; } else { Carry = 0; } ReturnList.push_back(Sum); } ReturnList.reverse(); return ReturnList; } Αρχικά αντιστρέφω τις λίστες (για να ξεκινάω τις προσθέσεις από την αρχή, και όχι από το τέλος όπως έκανες εσύ) και στη συνέχεια προσθέτω μηδενικά στην λίστα με τα λιγότερα ψηφία, ούτως ώστε οι λίστες μου να έχουν το ίδιο μέγεθος (και να μπορώ να τις προσθέτω ψηφίο προς ψηφίο). Μετά, ξεκινώντας από την αρχή, προσθέτω ένα-ένα τα ψηφία στην λίστα που θα επιστρέψω και την αντιστρέφω πάλι πριν την επιστρέψω (ώστε τα ψηφία να είναι με τη σωστή σειρά). 1
petran91 Δημοσ. 31 Μαΐου 2015 Μέλος Δημοσ. 31 Μαΐου 2015 Είναι λίγο δυσανάγνωστο αυτό που έχει γράψει, ειδικά στη 2η συνάρτησή σου. Αυτά έγραψα εγώ Αριθμός -> Λίστα std::list<int> IntToList(int Number) { if (Number < 0) { return std::list<int>(); } std::list<int> ReturnList = std::list<int>(); std::string NumBuffer = std::to_string(Number); for (auto c : NumBuffer) { // This will only work if we're using ASCII and will most likely break if another encoding is used. int NumberToAdd = c - '0'; ReturnList.push_back(NumberToAdd); } return ReturnList; } Βάζω τα ψηφία του αριθμού σε ένα string και στη συνέχεια παίρνω το κάθε ψηφίο, το μετατρέπω από char σε int και το βάζω σε μια λίστα. Η for αυτή λέγεται range-based for και είναι ιδιαίτερα χρήσιμη σε περιπτώσεις με iterators. Εσύ το χειρίστηκες με αριθμητικό τρόπο, που φυσικά δεν είναι λάθος, απλώς είναι ένας άλλος τρόπος να γίνει το ίδιο πράγμα. Πρόσθεση λιστών std::list<int> AddNumberLists(std::list<int> FirstList, std::list<int> SecondList) { std::list<int> ReturnList = std::list<int>(); int Carry = 0; FirstList.reverse(); SecondList.reverse(); // If the lists are of different size, add 0s to the shorter list to make them even. if (FirstList.size() > SecondList.size()) { for (int i = 0; i <= (FirstList.size() - SecondList.size()); i++) { SecondList.push_back(0); } } else if (FirstList.size() < SecondList.size()) { for (int i = 0; i <= (SecondList.size() - FirstList.size()); i++) { FirstList.push_back(0); } } auto FirstIter = FirstList.begin(); auto SecondIter = SecondList.begin(); for (; (FirstIter != FirstList.end()) && (SecondIter != SecondList.end()); FirstIter++, SecondIter++) { int Sum = *FirstIter + *SecondIter + Carry; if (Sum > 9) { Carry = 1; Sum -= 10; } else { Carry = 0; } ReturnList.push_back(Sum); } ReturnList.reverse(); return ReturnList; } Αρχικά αντιστρέφω τις λίστες (για να ξεκινάω τις προσθέσεις από την αρχή, και όχι από το τέλος όπως έκανες εσύ) και στη συνέχεια προσθέτω μηδενικά στην λίστα με τα λιγότερα ψηφία, ούτως ώστε οι λίστες μου να έχουν το ίδιο μέγεθος (και να μπορώ να τις προσθέτω ψηφίο προς ψηφίο). Μετά, ξεκινώντας από την αρχή, προσθέτω ένα-ένα τα ψηφία στην λίστα που θα επιστρέψω και την αντιστρέφω πάλι πριν την επιστρέψω (ώστε τα ψηφία να είναι με τη σωστή σειρά). Αρχικά σε ευχαριστώ πολύ για τον χρόνο που αφιέρωσες. Για την πρώτη συνάρτηση απλά να πω ότι δεν γνωρίζω καθόλου για τα strings γι αυτό δεν το προσέγγισα έτσι(δεν είμαι σε σχολή προγραμματισμού, μια εισαγωγή στην C κάναμε.). Αλλά όπως ανέφερες κι εσύ δουλεύει και το δικό μου οπότε εντάξει μέχρι εδώ. Η διαφορά σε αυτά που γράψαμε από ότι καταλαβαίνω είναι ότι οι στην δική σου εκδοχή οι λίστες έχουν το ίδιο μέγεθος. Επίσης η άσκηση ζητάει τα ορίσματα της function να έχουν iterators αρχή και τέλους της πρώτης list, αρχής και τέλους της δεύτερης και αρχής της πρώτης. Εσύ έδωσες τις λιστες ολόκληρες. Είναι το ίδιο πράγμα? Τέλος παρατηρώ ότι εγώ προσπάθησα να γυρίσω iterator και όχι ολόκληρη λίστα. 'Ισως εκεί έγινε το μπέρδεμα. Θα κάνω κάποιες διορθώσεις σύμφωνα με τον δικό σου κώδικα και θα επιστρέψω. Ευχαριστώ και πάλι!
Moderators Kercyn Δημοσ. 31 Μαΐου 2015 Moderators Δημοσ. 31 Μαΐου 2015 Ναι, δε γίνεται να μην έχουν το ίδιο μέγεθος. Αλλιώς πώς θα τις προσθέσεις; Όταν πας να προσθέσεις ένα ψηφίο και στην άλλη λίστα δεν υπάρχει αντίστοιχο ψηφίο (έστω και 0) θα πάρεις λάθος.
petran91 Δημοσ. 31 Μαΐου 2015 Μέλος Δημοσ. 31 Μαΐου 2015 Ναι, δε γίνεται να μην έχουν το ίδιο μέγεθος. Αλλιώς πώς θα τις προσθέσεις; Όταν πας να προσθέσεις ένα ψηφίο και στην άλλη λίστα δεν υπάρχει αντίστοιχο ψηφίο (έστω και 0) θα πάρεις λάθος. Γι αυτό το λόγο ξεκινάω την πρόσθεση από το τέλος των λιστών: if ((*Aend+*Bend+c)<10){ *Cbeg=*Aend+*Bend+c; c=0;} if ((*Aend+*Bend+c)>9){ *Cbeg=(*Aend+*Bend+c)%10; c=1;} *Aend=0; *Bend=0; if (Abeg!=Aend){ Aend--;} if (Bbeg!=Bend){ Bend--;} Και μετά κάθε φορά μηδενίζω το Aend και Βend πριν τα μετακινήσω μια θέση πίσω, ώστε αν μία από τις 2 λίστες φτάσει στο τέλος της και δεν ξαναλάξει ο iterator θέση, να μην μπορεί η τιμή στην συγκεκριμένη θέση να επηρεάσει την πρόσθεση. Δεν μπορώ να καταλάβω γιατί βγάζει λάθος. ΥΓ. Έχω μία κενή λίστα. Αν ξεκινάω να γράφω μέσα της ξεκινώντας από το .begin() είναι λάθος? Πρέπει να έχω δηλώσει το μέγεθος της μήπως στην αρχή?
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα