Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Καλησπέρα σας,

έχω να παραδώσω μία άσκηση και χρειάζομαι τα φώτα σας.

Η άσκηση είναι αυτή:
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 της τρίτης λίστας, η την τρίτη λίστα ολόκληρη.

Μπορείτε να με βοηθήσετε σε αυτό?

Ευχαριστώ εκ των προτέρων.
 

 

Υ.Γ Είμαι πολύ αρχάριος στη γλώσσα οπότε όσο πιο απλά γίνεται σας παρακαλώ οι απαντήσεις σας :D

 

EDIT: Την βρήκα την άκρη μετά από ώρες ταλαιπωρίας... Έχω segmentation fault βέβαια για το β ερώτημα αλλά θα βρεθεί άκρη ελπίζω :P

Επεξ/σία από petran91
Δημοσ.

Βγαίνω εκτός λίστας λογικά. Δεν το έχω διορθώσει ακόμα.

Παραθέτω τον κώδικα για όποιον θέλει να το δει. Η προβληματική συνάρτηση είναι η τελευταία.
(έχω πράγματα που δεν χρειάζονται μέσα, απλά τα είχα επειδή έκανα δοκιμές).

#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
Δημοσ.

Είναι λίγο δυσανάγνωστο αυτό που έχει γράψει, ειδικά στη 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;
}

 

 

 

Αρχικά αντιστρέφω τις λίστες (για να ξεκινάω τις προσθέσεις από την αρχή, και όχι από το τέλος όπως έκανες εσύ) και στη συνέχεια προσθέτω μηδενικά στην λίστα με τα λιγότερα ψηφία, ούτως ώστε οι λίστες μου να έχουν το ίδιο μέγεθος (και να μπορώ να τις προσθέτω ψηφίο προς ψηφίο).

Μετά, ξεκινώντας από την αρχή, προσθέτω ένα-ένα τα ψηφία στην λίστα που θα επιστρέψω και την αντιστρέφω πάλι πριν την επιστρέψω (ώστε τα ψηφία να είναι με τη σωστή σειρά).

  • Like 1
Δημοσ.

Είναι λίγο δυσανάγνωστο αυτό που έχει γράψει, ειδικά στη 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
Δημοσ.

Ναι, δε γίνεται να μην έχουν το ίδιο μέγεθος. Αλλιώς πώς θα τις προσθέσεις; Όταν πας να προσθέσεις ένα ψηφίο και στην άλλη λίστα δεν υπάρχει αντίστοιχο ψηφίο (έστω και 0) θα πάρεις λάθος.

Δημοσ.

Ναι, δε γίνεται να μην έχουν το ίδιο μέγεθος. Αλλιώς πώς θα τις προσθέσεις; Όταν πας να προσθέσεις ένα ψηφίο και στην άλλη λίστα δεν υπάρχει αντίστοιχο ψηφίο (έστω και 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() είναι λάθος? Πρέπει να έχω δηλώσει το μέγεθος της μήπως στην αρχή?

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...