Modificar nodo en una lista dinámica.

Iniciado por Abril7, 3 Marzo 2017, 16:48 PM

0 Miembros y 1 Visitante están viendo este tema.

Abril7

Hola, estoy haciendo una lista dinámica con nodos, y el programa ya esta básicamente funcionando completo menos la función de editByValue (Modificar por valor), creo que la lógica que uso esta mal o quizas la función compare, la verdad no detecto que hago mal, si me pueden decir lo apreciaria, gracias. Hicé 3 intentos diferentes de la misma funcion y ninguna funciona si me pueden decir como hacer funcionar cualquiera me sirve, otra cosa entiendo que no entrará al ciclo porque first lo inicializo como NULL pero aunque quite eso no funciona, preferiria un metodo que me deje incilizar a first con NULL así evito errores. El programa compila y todo nada mas esa función no sirve.

Muchas gracias.

Aquí el código completo

#include <iostream>
using namespace std;

class Nodo{
    public:
        string element;
        Nodo *next;
        Nodo(string element){this->element=element;next=NULL;}
        string getElement(){return element;}
};

class List{
   private:
    Nodo *first= NULL;
    Nodo *last = NULL;
   public:
    void insertFirst(string element);
    void insertLast(string element);
    void insertByPos(string element, int pos);
    void deleteFirst();
    void deleteLast();
    void deleteByPos(int pos);
    void destroy();
    void show();
    void editByPos(string value,int pos);
    void editByValue(string value, string newValue);
    bool isEmpty(Nodo *first);
    int listSize();
};

void List::insertFirst(string element)
{
    Nodo *temp = new Nodo(element);
    temp->next=NULL;
    if(isEmpty(first))
    {
        first=temp;
    }
    else{
        temp->next=first;
        first=temp;
    }
}
void List::insertLast(string element)
{
    Nodo *temp = new Nodo(element);
    temp->next=NULL;

    if(isEmpty(first)){
        first=last=temp;
    }
    else{
    Nodo *aux;
    aux = first;
    while (aux->next != NULL)
    {
        aux = aux->next;
    }
    aux->next=temp;

    cout<<"\tElement "<<element<<" was inserted at the end successfully."<<endl;}

}

int List::listSize()
{
    int c= 0;
    Nodo *aux;
    aux=first;
    while(aux != NULL){
    aux = aux->next;
    c++;
}
return c;
}
void List::insertByPos(string element, int pos)
{
    Nodo *temp = new Nodo(element);
    temp->next=NULL;

    if(isEmpty(first))
    {
        first=temp;
        cout<<"\tYou added the first element to the list successfully."<<endl;
    }
    else if (pos==1){
        insertFirst(element);
    }
    else if (pos == (listSize()+1)){
        insertLast(element);
    }
    else if(pos>1 && pos< (listSize() + 1))
    {
        Nodo *aux, *aux2;
        aux=first;
        for (int i=1;i<pos;i++)
        {
            aux2 = aux;
            aux = aux->next;
        }
        aux2->next=temp;
        temp->next = aux->next;
        delete(aux);

        cout<<"\tThe element: "<<element<<" was inserted successfully on the position: "<<pos<<"."<<endl;
    }
    else if(pos > (listSize()+1) or pos<0){
        cout<<"\tError: The position that you are trying to use is invalid."<<endl;
        cout<<"\tThe list only have '"<<listSize()<<"' elements. Try with one that is on range."<<endl;
    }
}
void List::deleteFirst()
{
    if(isEmpty(first)){
        cout<<"\tThe list is empty, you can not delete elements."<<endl;
    }
    else{
            if(first==last)
            {
                first=last=NULL;
                cout<<"\tThe first element was removed successfully."<<endl;
            }
            else
            {
                Nodo *aux=first;
                first=first->next;
                delete aux;
                cout<<"\tThe first element was removed successfully."<<endl;
            }
        }
}
void List::deleteLast()
{

    if(isEmpty(first)){
        cout<<"\tThe list is empty, you can not delete elements."<<endl;}

    else{
        Nodo *aux=first;
        while(aux!=NULL)
        {
            if(first==last)
            {
                first=last=NULL;
                cout<<"\tThe last element was removed successfully."<<endl;
            }
            else if(aux->next==last)
            {
                Nodo *temp = last;
                last=aux;
                last->next=NULL;
                delete temp;
                cout<<"\tThe last element was removed successfully."<<endl;
            }
        aux=aux->next;
        }
    }
}
void List::deleteByPos(int pos)
{
    if(isEmpty(first)){
        cout<<"\tYou can not delete anything.The list is empty."<<endl;
        }
    else if (pos==1){
        deleteFirst();
    }
    else if(pos==listSize()){
        deleteLast();
    }
    else if(pos>1 && pos< (listSize() + 1)){
        Nodo *aux, *aux2;
        aux=first;
        for (int i=1;i<pos;i++)
        {
            aux2 = aux;
            aux = aux->next;
        }
        aux2->next=aux->next;
        delete(aux);

        cout<<"\tThe element was removed successfully of the list."<<endl;
    }
    else if(pos > (listSize()+1) or pos<0){
        cout<<"\tError: The position that you are trying to use is invalid."<<endl;
        cout<<"\tThe list only have '"<<listSize()<<"' elements. Try with one that is on range."<<endl;
    }
}

void List::destroy()
{
    Nodo *aux;

    while(first != NULL)
    {
        aux=first;
        first = first->next;
        delete(aux);
    }
    cout<<"\tThe list was destroyed..."<<endl;
}
void List::show()
{
    if(isEmpty(first)){
        cout<<"The list is Empty."<<endl;}
    else{
    Nodo *aux;
    aux = first;
    while(aux != NULL)
    {
        cout<<aux->element<<endl;
        aux= aux->next;
    }
    }
}
void List::editByPos(string value,int pos)
{
    if(isEmpty(first)){
        cout<<"\tYou can not modify anything.The list is empty."<<endl;
        }
    else if (pos==1){

        Nodo *temp = new Nodo(value);
        temp->next=first->next;
        first=temp;

         cout<<"The first element is now called '"<<value<<"'."<<endl;
    }
    else if(pos>0 && pos <= (listSize())){
        Nodo *temp= new Nodo(value);
        temp->next=NULL;

        Nodo *aux, *aux2;
        aux=first;
        for (int i=1;i<pos;i++)
        {
        aux2 = aux;
        aux = aux->next;
        }
        aux2->next=temp;
        temp->next=aux->next;
        delete(aux);
        cout<<"\tThe element was modified successfully."<<endl;
        }
    else if(pos > (listSize()) or pos<=0){
        cout<<"\tError: The position that you are trying to use is invalid."<<endl;
        cout<<"\tThe list only have '"<<listSize()<<"' elements. Try with one that is on range."<<endl;
    }
}
void List::editByValue(string value, string newValue)
{
//Primer intento
    Nodo *aux = new Nodo(value);
    aux=first;
    bool found=false;
    if(first != NULL){
        while(aux != NULL && found != true){string temp= aux->element;
            if( temp.compare(value)== 0){
                  aux->element= newValue;
            found = true;
            }
            aux=aux->next;
        }
        if(!found){
            cout<<"\t There is not an element with that name."<<endl;
        }
    }else{
        cout<<"\t The list is empty."<<endl;
    }
}
/* Segundo intento con una logica similar pero diferente codigo
    *Nodo *temp = new Nodo(newValue);
    if(isEmpty(first)){
        cout<<"\tYou can not modify anything.The list is empty."<<endl;
        }

    Nodo *aux,*aux2;
    Nodo *var = first;
    do{
    if(var->element.compare(value) != 0)
    {
        var=var->next;

    }}while(var->next != NULL);

    var->element = newValue; */

/*   Tercer intento, tampoco funciona
Nodo *temp = new Nodo(newValue);
    if(isEmpty(first)){
        cout<<"\tYou can not modify anything.The list is empty."<<endl;
        }

    Nodo *aux,*aux2;
    Nodo *var = first;
    do{
    if(var-> element == value)
    {
        aux2=aux;
        aux=aux->next;
        temp->next=aux->next;
        aux2->next=temp;
        delete(aux);}
} */

bool List::isEmpty(Nodo *first)
{
    return(first == NULL)? true : false;
}

int main ()
{
    List a;
    int option;
    int x=0;
    string name;
    int op;
    int opp;
while(x==0){
    cout<<"What do you wanna do? 1) Add 2) Delete 3) Show 4)Edit 5)Exit"<<endl;
    cin>>option;

    switch(option)
    {
        case 1:{
            cout<<"How do you want to add? \n 1)At the beginning \n 2)At the end \n 3)In 'n' position "<<endl;
            cin>>op;
            cout<<"Give me a name to add to the queue:"<<endl;
            cout<<" "; cin>>name;
            cout<<endl;
            if(op==1){
                a.insertFirst(name);}
            else if (op==2){
                a.insertLast(name);}
            else if(op==3){
                int num;
                cout<<"In which position do you want to insert the node?"<<endl;
                cin>>num;
                a.insertByPos(name,num);}
            }break;
        case 2:{
            int op,pos;
            cout<<"How do you want to remove?: \n 1)At the beginning \n 2)At the end \n 3)In 'n' position \n 4)Delete all the list"<<endl;
            cin>>op;
            if(op==1){
                a.deleteFirst();}
            else if (op==2){
                a.deleteLast();}
            else if(op==3){
                int pos=0;
                cout<<"In which position do you want to remove the element?"<<endl;
                cin>>pos;
                a.deleteByPos(pos);}
            else if(op==4){
                a.destroy();}

            }break;
        case 3:{
            a.show();
            }break;
        case 4:{
            int opt;
            string value,newName;
            cout<<"Do you want to: \n 1)Edit by position \n 2)Edit by value \n "<<endl;
            cin>>opt;
            cout<<"What's the new value?"<<endl;
            cin>>value;
            if(opt==1){
                int pos;
                cout<<"In which position do you want to edit?"<<endl;
                cin>>pos;
                a.editByPos(value,pos);}
            else if (opt==2){
                cout<<"For which value do you want to change?"<<endl;
                cin>>newName;
                a.editByValue(value, newName);}
            }break;
        case 5:
            x=1;
    }
}
return 0;
}

ivancea96

Tal como pusiste en el tercer intento, puedes comparar cadenas con == o != sin problema.
El primer intento, a simple vista, parece correcto. Si tal, puedes colocar couts para ver exactamente qué hace el programa y ver dónde podría estar el fallo (o depurarlo como tú quieras, vamos). Más que nada para ver por dónde pasa, que valores compara, etc.

Por cierto:
Código (cpp) [Seleccionar]
Nodo *aux = new Nodo(value);
aux=first;

Creas ese nodo y no lo destruyes (En general, no deberías crearlo, no hace nada, le pones otro valor al momento a la variable)

En el main, pusiste:
Código (cpp) [Seleccionar]
cout<<"What's the new value?"<<endl;
cin>>value;

Querrías decir que "old value", o "the value to find". Error sintáctico, pero cuidado no vaya a tener que ver a la hora de testearlo.

Abril7

Intentaré lo de los couts, eliminé la declaracion del nodo y acomodé lo de las variables que sí, me revolví. Pero ahora que estoy provando con los couts e imprimo las variables que comparo antes de hacerlo veo que si estan bien pero por alguna razón se imprime un 0 antes de mi variable vieja y así nunca hará la comparación correctamente, supongo que es el resultado del bool, pero como lo quito?

Perdona si mis preguntas son muy tontas, no llevo mucho tiempo programando.

Lo que me imprime:


Como se ve el código:

void List::editByValue(string oldValue, string newValue)
{

    Nodo *aux;
    aux=first;
    bool found=false;
    if(first != NULL){
        while(aux != NULL && found != true){cout<<aux->element<<endl;
        cout<<oldValue<<endl;
            if( aux->element.compare(oldValue)== 0){
                  aux->element= newValue;
            found = true;
            }
            aux= aux->next;
            cout<<aux->next;
        }
        if(!found){
            cout<<"\t There is not an element with that name."<<endl;
        }
    }else{
        cout<<"\t The list is empty."<<endl;
    }
}


ivancea96

Pusiste: cout<<aux->next;
next es un puntero. Como aparece un 0, significa que el siguiente es NULL. Es correcto.
Tal vez quisiste poner aux->element (antes de la línea aux = aux->next, eso sí)

De todos modos, pusiste Luis como valor antiguo. No exise, así que no tiene que hacer nada.

En la imagen aparece un error 0xC0000005. De este error está bien que te acujerdes (es de los pocos que verás "normalmente"). Es un error por, generalmente, acceder a una zona de memoria que no debes.

Pero no te preocupes. En este caso es por esto:
Código (cpp) [Seleccionar]
aux= aux->next;
cout<<aux->next;

Si aux->next es NULL, luego, en el cout, tratas de acceder a aux->next, es decir, NULL->next. Pero bueno, sería cambiar el orden de esas líneas y listo (o poner element, como puse arriba)

Y lo dicho, tienes mal la salida del menú:
Código (cpp) [Seleccionar]
            cout<<"What's the new value?"<<endl;
            cin>>value;
            if(opt==1){
                int pos;
                cout<<"In which position do you want to edit?"<<endl;
                cin>>pos;
                a.editByPos(value,pos);}
            else if (opt==2){
                cout<<"For which value do you want to change?"<<endl;
                cin>>newName;
                a.editByValue(value, newName);}

Primero pides el new value. Luego, lo pides de nuevo. El primer "nuevo valor", es el que pasas como antiguo. Revisa esos couts y cómo llamas a la función.

Abril7

Si si, estuve revisando el código en todo lo que me dijiste y ya vi que mal lo puse en el main jaja. Creo que estaba demasiado dormida cuando hice esa parte, en si pedia el mismo valor para todo. Cambié eso y ya funciona perfectamente. Muchisimas gracias de verdad! Me ayudaste demasiado!