Add the elements of two linked lists in a third list

1

The idea is to represent a three-digit sum

   6  8  9  <---- valores de lista 1.
   5  7  4   <----- valores lista 2.
 -------------
 1 2  6  3   <------ valores lista 3.

So far I get the result of the sum, but taking the values from left to right.

  6 8 9
  5 7 4
_________
1 4 6 1  ---> regresa el resultado de sumar ( 986 + 474 )

Now try to enter the data in the opposite order in the first two lists and nothing.

I show you the code:

#include "iostream"
using namespace std;

struct nodo
{
 int numero;
 struct nodo* sig;
 struct nodo* ant;  
};
typedef struct nodo*Lista;

void insertarValores(Lista &lista,int digito)
{
Lista nuevo;
nuevo = new(struct nodo);
nuevo ->numero=digito;
    if(lista==NULL){
        lista=nuevo;
        lista->sig=NULL;
        lista->ant=NULL;    
    }
    else
    {
        nuevo->sig=lista;
        nuevo->ant=lista->ant;
        lista->ant=nuevo;
        lista=nuevo;
    }   

}
void insertarFinal(Lista & lista,int digito)
{
 Lista nuevo,aux =lista;    
 nuevo = new(struct nodo);
 nuevo->numero=digito;
 nuevo->sig=NULL;
 if(aux==NULL)
 {
    lista=nuevo;
 }
 else
   {
       while(aux->sig!=NULL)
       aux=aux->sig;   
       aux->sig=nuevo;

   }

}

void mostrar(Lista lista)
{

Lista aux =new (struct nodo);

aux=lista;
cout<<"\n";
    while(aux!=NULL){
    cout<<"   "<<aux->numero;
        aux=aux->sig;

    }   
}

void sumar(Lista &lista1,Lista &lista2,Lista &listaResultado)
 {
 Lista l1=lista1, l2=lista2;
  int acarreo=0;
   while (l1 != NULL && l2 != NULL)
  {
   int suma = l1->numero + l2->numero+acarreo;
   if(suma>=10)
     {
      insertarFinal(listaResultado, suma%10);
      acarreo=1;
     }
    else 
    {
    insertarFinal(listaResultado, suma%10);
    acarreo=0;  
    }
    l1 = l1->sig;
    l2 = l2->sig;
  }
  insertarFinal(listaResultado,acarreo);
}

int main(){
Lista arriba=NULL;
Lista abajo=NULL;
Lista resultado=NULL;
int L1,L2;
cout<<"Ingrese los valores a sumar de la lista 1 (arriba)"<<endl;
for(int i=0;i<3;i++)
{   cout<<"Lista 1.\n\tValor "<<i+1<<" ";
    cin>>L1;
    //insertarValores(arriba,L1);
    insertarFinal(arriba,L1);
    mostrar(arriba);
        cout<<"\n";
}
system("cls");
cout<<"Ingrese los valores a sumar de la lista 2 (abajo)"<<endl;
for(int i=0;i<3;i++)
{   cout<<"Lista 2.\n\tValor "<<i+1<<" ";
    cin>>L2;
    //insertarValores(abajo,L2);
insertarFinal(abajo,L2);
mostrar(abajo);
cout<<"\n";
}

system("cls");
mostrar(arriba); 
cout<<"\n+ ";
mostrar(abajo);
cout<<"\n___________________";

sumar(arriba,abajo,resultado);
mostrar(resultado);
}
    
asked by tpmtu 14.12.2016 в 22:21
source

3 answers

1

I see you use a doubly linked list so you should have no problem traversing the numbers from least significant to most significant.

Proposal

I would advise you to pass the list to a number and then let the system be the one in charge of the carries and overflows; the function to pass your Lista to number would be:

int lista_a_numero(const Lista &lista)
{
    int resultado{}, arrastre{1};

    for (const nodo *actual = ultimo(lista); actual; actual = actual->ant)
    {
        resultado += (actual->numero * arrastre);
        arrastre *= 10;
    }

    return resultado;
}

With this function you could transform the list into a number. If you notice, I'm using a function to point to the last node in a list, which looks like this:

const nodo *ultimo(const nodo *actual)
{
    if (actual->sig)
        return ultimo(actual->sig);

    return actual;
}

Now you only need a function that does the reverse operation to get this:

int valor1 = lista_a_numero(lista1);
int valor2 = lista_a_numero(lista2);
Lista listaSuma = numero_a_lista(valor1 + valor2);

The function to transform from number to list would be something like this:

Lista numero_a_lista(int numero)
{
    nodo *resultado = new nodo{numero % 10};
    numero /= 10;

    while (numero)
    {
        resultado = new nodo{numero % 10, resultado};
        resultado->sig->ant = resultado;
        numero /= 10;
    }

    return resultado;
}

With this proposal the code would look like this:

int main()
{
    Lista lista1 = numero_a_lista(689);
    Lista lista2 = numero_a_lista(574);

    int valor1 = lista_a_numero(lista1);
    int valor2 = lista_a_numero(lista2);
    Lista listaSuma = numero_a_lista(valor1 + valor2);

    std::cout << valor1 << " + " << valor2 << " = ";

    for (nodo *actual = listaSuma; actual; actual = actual->sig)
        std::cout << actual->numero;

    return 0;
}

[Whose departure is] :

689 + 574 = 1263

Tips

In C ++ it is not necessary to prepend struct to refer to a structure ; so your node would look like this:

struct nodo
{
 int numero;
 nodo* sig;
 nodo* ant;
};

From C ++ 11 you can use the uniform initialization to give value to the members of your structure in the same site that they declare , so you save yourself creating a constructor and you ensure you get controlled values:

struct nodo
{
 int numero = 0;
 nodo* sig = nullptr;
 nodo* ant = nullptr;
};

To create aliases of types, the typedef has a confusing syntax, from C ++ 11 you can simplify the alias with the instruction using :

using Lista = nodo *;

Note that it does not require the struct before nodo .

As for this alias, it is a terrible idea , nefarious, horrible, inadequate, improper, illogical and many other negative qualifiers. A nodo is not a Lista , conceptually they are different things ... it's as if you were saying that a spark plug is a car; create an object Lista do not say that a nodo is a Lista .

Use const always do not modify objects , that can help the compiler to make optimizations and make others who read the code know your intentionality:

// mostrar una lista no requiere modificarla
void mostrar(const Lista lista);
// no se requiere modificar lista1 ni lista2 para sumar
void sumar(const Lista &lista1, const Lista &lista2, Lista &listaResultado);
    
answered by 19.12.2016 / 12:55
source
0

Hi, I think you've messed a little in the function suma () and it should be simpler, so I gave myself the task of altering your code a bit

void sumar(Lista &lista1, Lista &lista2, Lista &listaResultado){    
Lista l1=lista1, l2=lista2;

while (l1 != NULL && l2 != NULL) {

    int suma = l1->numero + l2->numero;
    insertarFinal(listaResultado, suma);
    l1 = l1->sig;
    l2 = l2->sig;
  }
}

Main

int main() {

    Lista lista1 = NULL, lista2 = NULL,listaSuma=NULL;
    int n;

   //Llenamos primer lista
    for (int i = 0; i < 3; i++) {
       cout << "Ingrese el valor lista 1 " << endl;
       cin >> n;
       insertarFinal(lista1, n);
    }
    cout << endl;

    //Llenamos segunda lista
    for (int i = 0; i < 3; i++) {
       cout << "Ingrese el valor lista 2" << endl;
       cin >> n;
       insertarFinal(lista2, n);
    }
    cout << endl;

    sumar(lista1, lista2, listaSuma);
    mostrar(listaSuma);

   cin.get();
   cin.get();
   return 0;
}

PS: Do not forget to free the memory.

    
answered by 15.12.2016 в 01:33
0

basically you create a list 3 and insert the nodes of both lists with the primitives of inserting list in the third list

    
answered by 19.12.2016 в 16:44