11-11-2011, 11:38
Hola gente,
Mi primer post referido específicamente a mi carrera. Hará unos diez días que me tomaron el recuperatorio del primer parcial de esta queridísima materia. La parte práctica pedía realizar un programa que intercambie dos nodos de una lista doblemente enlazada, compare lexicográficamente dos cadenas (esta función se pedía usarla en la función intercambiar),y copiar aquellos nodos donde los nombres de socio empiecen con una letra tipeada por el usuario.
Bueno, el profesor nos dijo que el que entrega el programa funcionando tiene más chances de aprobar. Pero tiene que estar perfecto (por eso también la razón del post Jaja).
Aclaración: La función copiar si bien funciona no está del todo bien, pues imprimo el resultado en la misma función y no en el main. Y la función intercambiar a veces al imprimir se vuelve loca (esto último es en lo que quiero que algún alma generosa me ayude).
Al que le interese y desee ayudarme bienvenido sea.
A continuación mi código:
Les adjunto el enunciado del parcial.
Saludos!
Mi primer post referido específicamente a mi carrera. Hará unos diez días que me tomaron el recuperatorio del primer parcial de esta queridísima materia. La parte práctica pedía realizar un programa que intercambie dos nodos de una lista doblemente enlazada, compare lexicográficamente dos cadenas (esta función se pedía usarla en la función intercambiar),y copiar aquellos nodos donde los nombres de socio empiecen con una letra tipeada por el usuario.
Bueno, el profesor nos dijo que el que entrega el programa funcionando tiene más chances de aprobar. Pero tiene que estar perfecto (por eso también la razón del post Jaja).
Aclaración: La función copiar si bien funciona no está del todo bien, pues imprimo el resultado en la misma función y no en el main. Y la función intercambiar a veces al imprimir se vuelve loca (esto último es en lo que quiero que algún alma generosa me ayude).
Al que le interese y desee ayudarme bienvenido sea.
A continuación mi código:
Spoiler: Mostrar
//Librerías.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Estructura.
struct nodo
{
char nombre[50];
int socio;
struct nodo *Siguiente;
struct nodo *Anterior;
struct nodo *Inicio;
struct nodo *Fin;
int tam;
};
//Prototipos de las funciones.
int insertar (struct nodo *Lista , char *n, int s);
struct nodo *intercambiar (struct nodo *Lista, char *cadena1, char *cadena2);
int comparar(char *cad1,char *cad2);
void *copiar(struct nodo *Lista, char letra);
int menu (struct nodo *Lista);
void imprimir (struct nodo *Lista);
//---------------------------------------MAIN-------------------------------------------//
int main (void)
{
struct nodo *lista;
lista=malloc(sizeof(struct nodo));
char *nom;
nom=malloc(50);
int opcion=1;
int soc;
int aux;
char *str1, *str2;
char l;
//Asignación de memoria.
str1=malloc(50);
str1=malloc(50);
//Incicialización de variables.
lista->Inicio=NULL;
lista->Fin=NULL;
lista->tam=0;
while (opcion!=4)
{
opcion=menu(lista);
switch (opcion)
{
case 4:
printf ("\nFin de la ejecución.\n");
exit(-1);
break;
case 0:
printf ("\nIngrese un nombre:");
scanf ("%s",nom);
printf ("\nIngrese nro. de socio:");
scanf ("%d",&soc);
insertar (lista,nom, soc);
imprimir(lista);
printf ("\n%d elementos.\n",lista->tam);
break;
case 1:
printf ("\nIngrese primer nombre:");
scanf ("%s",str1);
printf ("\nIngrese segundo nombre:");
scanf ("%s",str2);
intercambiar (lista,str1,str2);
imprimir (lista);
break;
case 2:
printf ("\nIngrese primer nombre:");
scanf ("%s",str1);
printf ("\nIngrese segundo nombre:");
scanf ("%s",str2);
aux = comparar (str1,str2);
if (aux==0)
printf ("\nCadenas iguales.\n");
if (aux==1)
printf ("\nPrimera cadena mayor.\n");
if (aux==-1)
printf ("\nPrimera cadena menor.\n");
break;
case 3:
printf ("\nIngrese letra:");
scanf ("\n%c",&l);
getchar();
copiar (lista,l);
}
}
return 0;
}
//---------------------------------------MENU-------------------------------------------//
int menu (struct nodo *Lista)
{
int eleccion;
if (Lista->tam==0)
{
printf ("\nElija una de las opciones que aparecen en pantalla:\n");
printf ("\n0-Insertar nuevo nodo.\n1-Salir.\n");
printf ("\nOpción:");
scanf ("%d",&eleccion);
if (eleccion==1)
eleccion=4; //Para que coincida con el menú de abajo.
}
else
{
printf ("\nElija una de las opciones que aparecen en pantalla:\n");
printf ("\n0-Insertar nuevo nodo.\n1-Intercambiar nodos.\n2-Comparar nodos.\n3-Copiar nodos.\n4-Salir.\n");
printf ("\nOpción:");
scanf ("%d",&eleccion);
}
return eleccion;
}
//---------------------------------INSERTAR NUEVO NODO----------------------------------//
int insertar (struct nodo *Lista , char *n, int s)
{
struct nodo *Nuevo, *Actual;
int insert;
int i=0;
//Reserva memoria para el nuevo nodo.
if ( (Nuevo = malloc (sizeof (struct nodo) ) ) == NULL)
return -1;
//Recorre el nombre/cadena ingresado por el usuario.
for( i=0; *(n+i)!='\0'; i++ )
{
Nuevo->nombre[i] = *(n+i); //Y lo almacena en el nuevo nodo.
}
Nuevo->nombre[i]='\0'; //Agrega el caracter NULL al final de la cadena.
Nuevo->socio=s; //Guarda el nro. de socio ingresado en el nuevo nodo.
if (Lista->tam==0) //Si la lista está está vacía.
{
Nuevo->Anterior=Lista->Inicio;
Nuevo->Siguiente=Lista->Fin;
Lista->Inicio=Nuevo;
Lista->Fin=Nuevo;
Lista->tam++; //Incrementa el tamaño de la lista, debido al nuevo nodo ingresado.
return 0;
}
else //Inserta después del último nodo ingresado.
{
Actual=Lista->Inicio;
while ( Actual->Siguiente != NULL && strcmp(n,Actual->nombre ) !=0 )
//Mientras el elemento siguiente al nodo actual no sea NULL y el nombre ingresado por
//el usuario sea distinto al nombre del nodo actual...
Actual=Actual->Siguiente; //Salta al siguiente nodo.
Nuevo->Anterior=Actual; //El nodo anterior a 'Nuevo' es el actual.
if (Actual->Siguiente==NULL)
Lista->Fin=Nuevo;
else Actual->Siguiente->Anterior=Nuevo;
Actual->Siguiente=Nuevo;
Lista->tam++; //Incrementa el tamaño de la lista, debido al nuevo nodo ingresado.
return 0;
}
}
//------------------------------------IMPRIMIR LISTA--------------------------------------//
void imprimir (struct nodo *Lista)
{
struct nodo *Inverso, *Actual;
int choice; //Variable para elegir modo de impresión de la lista.
printf ("\nElija una de las opciones que aparecen en pantalla:\n");
printf ("\n1-Imprimir lista.\n2-Imprimir lista al revés.\n");
printf ("\nOpción:");
scanf ("%d",&choice);
Actual=Lista->Inicio;
printf ("\n----->");
//Imprime desde el incio hasta el fin de la lista.
if (choice==1)
{
while (Actual!=NULL)
{
Inverso=Actual; //Cuando se termina de recorrer la lista, almacena el último nodo en 'Inverso'.
printf ("Nombre:%s/Socio:%d----->",Actual->nombre,Actual->socio); //Imprime nombre y socio del nodo.
Actual=Actual->Siguiente; //Salta al siguiente nodo.
}
}
//Imprime de atrás para delante.
if (choice==2)
{
while (Inverso!=NULL)
{
printf ("Nombre:%s/Socio:%d----->",Inverso->nombre,Inverso->socio);
Inverso=Inverso->Anterior; //Salta al nodo anterior.
}
}
}
//------------------------------------COMPARA NODOS-----------------------------------//
int comparar(char *cad1,char *cad2)
{
int i=0; //Auxiliar para recorrer cadenas.
while ( (*(cad1+i)!='\0') || (*(cad2+i)!='\0') )
{
if (*(cad1+i)<*(cad2+i)) //Si la primera cadena es menor a la segunda cadena...
return -1;
if (*(cad1+i)>*(cad2+i)) //Si la primera cadena es mayor a la segunda cadena...
return 1;
i++;
}
if (*(cad1+i)<*(cad2+i)) //Si la primera cadena es menor a la segunda cadena...
return -1;
else if (*(cad1+i)>*(cad2+i)) //Si la primera cadena es mayor a la segunda cadena...
return 1;
return 0; //Retorna la variable aux.
}
//------------------------------------INTERCAMBIA NODOS-------------------------------//
struct nodo *intercambiar (struct nodo *Lista, char *cadena1, char *cadena2)
{
struct nodo *Actual, *T1, *T2, *Aux1, *Aux2;
int i=0; //Variable auxiliar para recorrer cadenas.
//Asignación de memoria a variables auxiliares.
Aux1 = malloc (sizeof (struct nodo) );
Aux2 = malloc (sizeof (struct nodo) );
Actual = malloc (sizeof (struct nodo) );
//Memoria asignada.
//Recorremos la lista desde su primer nodo.
Actual=Lista->Inicio;
while (Actual!=NULL) //Mientras no se llegue el final de la lista...
{
if (comparar (Actual->nombre,cadena1)==0) //Al ser 0, quiere decir que las cadenas son iguales.
{
Aux1=Actual; //Guarda el nodo hallado (actual) en un auxiliar.
break;
}
//Si no encontro el nodo que buscamos se mueve el siguiente nodo.
else Actual=Actual->Siguiente;
}
//Si el primer nodo fue encontrado...
if (Aux1!=NULL)
{
//Recorremos la lista desde su primer nodo.
Actual=Lista->Inicio;
while (Actual!=NULL) //Mientras no se llegue el final de la lista...
{
if (comparar (Actual->nombre,cadena2)==0) //Al ser 0, quiere decir que las cadenas son iguales.
{
Aux2=Actual; //Guarda todo el nodo hallado (actual) en un auxiliar.
break;
}
//Si no encontro el nodo que buscamos se mueve el siguiente nodo.
else Actual=Actual->Siguiente;
}
//Si el segundo nodo fue encontrado...
if (Aux2!=NULL)
{
//Si el primer nodo es el primer elemento...
if (Aux1==Lista->Inicio)
{
//Muevo el segundo nodo al inicio de la lista y al primer nodo a la posición
//donde se encontraba el segundo nodo.
Lista->Inicio=Aux2;
Aux2->Anterior->Siguiente=Aux1;
}
//Si el segundo nodo es el primer elemento...
else if (Aux2==Lista->Inicio)
{
//Muevo el primer nodo al inicio de la lista y al segundo nodo a la posición
//donde se encontraba el primer nodo.
Lista->Inicio=Aux1;
Aux1->Anterior->Siguiente=Aux2;
}
//Si ninguno de los dos nodos hallados es el primer elemento de la lista.
else
{
Aux2->Anterior->Siguiente=Aux1;
Aux1->Anterior->Siguiente=Aux2;
}
//Almaceno el puntero que apunta al nodo anterior del primer nodo en una variable
//temporal.
T1 = Aux1->Anterior;
//Muevo el puntero que apunta al nodo anterior del segundo nodo al primer nodo.
Aux1->Anterior = Aux2->Anterior;
//Almaceno el puntero que apunta al nodo siguiente del primer nodo en una variable
//temporal.
T2 = Aux1->Siguiente;
//Si el primer nodo no es el último elemento...
if (Aux1!=Lista->Fin)
Aux1->Siguiente->Anterior=Aux2;
//Si es el último elemento...
Aux1->Siguiente=Aux2->Siguiente;
//Muevo el puntero que apunta al nodo anterior del primer nodo al segundo nodo.
Aux2->Anterior = T1;
//Si el segundo nodo no es el último elemento...
if (Aux2==Lista->Fin)
Aux2->Siguiente->Anterior=Aux1;
//Si es el último elemento...
Aux2->Siguiente=T2;
}
return Lista->Inicio; //Retorna el lo apuntado por el inicio de la lista.
}
else return NULL; //Retorna NULL si uno de los nodos no fue encontrado.
}
//-------------------------------------ARRAY DE NODOS---------------------------------//
void *copiar(struct nodo *Lista, char letra)
{
struct nodo *Actual;
int i=0; //Variable auxiliar para recorrer el array de punteros.
char *p[Lista->tam]; //Array de punteros, almacena los nombres que empiecen con la
//letra ingresada por el usuario.
Actual=Lista->Inicio; //Parte desde el primer elemento de la lista.
printf("\n----->");
while (Actual!=NULL) //Mientras no llegue al final de la lista...
{
if (Actual->nombre[0] == letra) //Si la primera letra del nombre del nodo que se
//está analizando es igual a letra...
{
p[i]=Actual->nombre; //Se guarda el nombre del nodo en un array de punteros.
printf ("%s----->",p[i]); //Imprime dicho nombre.
i++; //Incrementa la posición del array de punteros en 1.
}
Actual=Actual->Siguiente; //Nos corremos al siguiente nodo.
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Estructura.
struct nodo
{
char nombre[50];
int socio;
struct nodo *Siguiente;
struct nodo *Anterior;
struct nodo *Inicio;
struct nodo *Fin;
int tam;
};
//Prototipos de las funciones.
int insertar (struct nodo *Lista , char *n, int s);
struct nodo *intercambiar (struct nodo *Lista, char *cadena1, char *cadena2);
int comparar(char *cad1,char *cad2);
void *copiar(struct nodo *Lista, char letra);
int menu (struct nodo *Lista);
void imprimir (struct nodo *Lista);
//---------------------------------------MAIN-------------------------------------------//
int main (void)
{
struct nodo *lista;
lista=malloc(sizeof(struct nodo));
char *nom;
nom=malloc(50);
int opcion=1;
int soc;
int aux;
char *str1, *str2;
char l;
//Asignación de memoria.
str1=malloc(50);
str1=malloc(50);
//Incicialización de variables.
lista->Inicio=NULL;
lista->Fin=NULL;
lista->tam=0;
while (opcion!=4)
{
opcion=menu(lista);
switch (opcion)
{
case 4:
printf ("\nFin de la ejecución.\n");
exit(-1);
break;
case 0:
printf ("\nIngrese un nombre:");
scanf ("%s",nom);
printf ("\nIngrese nro. de socio:");
scanf ("%d",&soc);
insertar (lista,nom, soc);
imprimir(lista);
printf ("\n%d elementos.\n",lista->tam);
break;
case 1:
printf ("\nIngrese primer nombre:");
scanf ("%s",str1);
printf ("\nIngrese segundo nombre:");
scanf ("%s",str2);
intercambiar (lista,str1,str2);
imprimir (lista);
break;
case 2:
printf ("\nIngrese primer nombre:");
scanf ("%s",str1);
printf ("\nIngrese segundo nombre:");
scanf ("%s",str2);
aux = comparar (str1,str2);
if (aux==0)
printf ("\nCadenas iguales.\n");
if (aux==1)
printf ("\nPrimera cadena mayor.\n");
if (aux==-1)
printf ("\nPrimera cadena menor.\n");
break;
case 3:
printf ("\nIngrese letra:");
scanf ("\n%c",&l);
getchar();
copiar (lista,l);
}
}
return 0;
}
//---------------------------------------MENU-------------------------------------------//
int menu (struct nodo *Lista)
{
int eleccion;
if (Lista->tam==0)
{
printf ("\nElija una de las opciones que aparecen en pantalla:\n");
printf ("\n0-Insertar nuevo nodo.\n1-Salir.\n");
printf ("\nOpción:");
scanf ("%d",&eleccion);
if (eleccion==1)
eleccion=4; //Para que coincida con el menú de abajo.
}
else
{
printf ("\nElija una de las opciones que aparecen en pantalla:\n");
printf ("\n0-Insertar nuevo nodo.\n1-Intercambiar nodos.\n2-Comparar nodos.\n3-Copiar nodos.\n4-Salir.\n");
printf ("\nOpción:");
scanf ("%d",&eleccion);
}
return eleccion;
}
//---------------------------------INSERTAR NUEVO NODO----------------------------------//
int insertar (struct nodo *Lista , char *n, int s)
{
struct nodo *Nuevo, *Actual;
int insert;
int i=0;
//Reserva memoria para el nuevo nodo.
if ( (Nuevo = malloc (sizeof (struct nodo) ) ) == NULL)
return -1;
//Recorre el nombre/cadena ingresado por el usuario.
for( i=0; *(n+i)!='\0'; i++ )
{
Nuevo->nombre[i] = *(n+i); //Y lo almacena en el nuevo nodo.
}
Nuevo->nombre[i]='\0'; //Agrega el caracter NULL al final de la cadena.
Nuevo->socio=s; //Guarda el nro. de socio ingresado en el nuevo nodo.
if (Lista->tam==0) //Si la lista está está vacía.
{
Nuevo->Anterior=Lista->Inicio;
Nuevo->Siguiente=Lista->Fin;
Lista->Inicio=Nuevo;
Lista->Fin=Nuevo;
Lista->tam++; //Incrementa el tamaño de la lista, debido al nuevo nodo ingresado.
return 0;
}
else //Inserta después del último nodo ingresado.
{
Actual=Lista->Inicio;
while ( Actual->Siguiente != NULL && strcmp(n,Actual->nombre ) !=0 )
//Mientras el elemento siguiente al nodo actual no sea NULL y el nombre ingresado por
//el usuario sea distinto al nombre del nodo actual...
Actual=Actual->Siguiente; //Salta al siguiente nodo.
Nuevo->Anterior=Actual; //El nodo anterior a 'Nuevo' es el actual.
if (Actual->Siguiente==NULL)
Lista->Fin=Nuevo;
else Actual->Siguiente->Anterior=Nuevo;
Actual->Siguiente=Nuevo;
Lista->tam++; //Incrementa el tamaño de la lista, debido al nuevo nodo ingresado.
return 0;
}
}
//------------------------------------IMPRIMIR LISTA--------------------------------------//
void imprimir (struct nodo *Lista)
{
struct nodo *Inverso, *Actual;
int choice; //Variable para elegir modo de impresión de la lista.
printf ("\nElija una de las opciones que aparecen en pantalla:\n");
printf ("\n1-Imprimir lista.\n2-Imprimir lista al revés.\n");
printf ("\nOpción:");
scanf ("%d",&choice);
Actual=Lista->Inicio;
printf ("\n----->");
//Imprime desde el incio hasta el fin de la lista.
if (choice==1)
{
while (Actual!=NULL)
{
Inverso=Actual; //Cuando se termina de recorrer la lista, almacena el último nodo en 'Inverso'.
printf ("Nombre:%s/Socio:%d----->",Actual->nombre,Actual->socio); //Imprime nombre y socio del nodo.
Actual=Actual->Siguiente; //Salta al siguiente nodo.
}
}
//Imprime de atrás para delante.
if (choice==2)
{
while (Inverso!=NULL)
{
printf ("Nombre:%s/Socio:%d----->",Inverso->nombre,Inverso->socio);
Inverso=Inverso->Anterior; //Salta al nodo anterior.
}
}
}
//------------------------------------COMPARA NODOS-----------------------------------//
int comparar(char *cad1,char *cad2)
{
int i=0; //Auxiliar para recorrer cadenas.
while ( (*(cad1+i)!='\0') || (*(cad2+i)!='\0') )
{
if (*(cad1+i)<*(cad2+i)) //Si la primera cadena es menor a la segunda cadena...
return -1;
if (*(cad1+i)>*(cad2+i)) //Si la primera cadena es mayor a la segunda cadena...
return 1;
i++;
}
if (*(cad1+i)<*(cad2+i)) //Si la primera cadena es menor a la segunda cadena...
return -1;
else if (*(cad1+i)>*(cad2+i)) //Si la primera cadena es mayor a la segunda cadena...
return 1;
return 0; //Retorna la variable aux.
}
//------------------------------------INTERCAMBIA NODOS-------------------------------//
struct nodo *intercambiar (struct nodo *Lista, char *cadena1, char *cadena2)
{
struct nodo *Actual, *T1, *T2, *Aux1, *Aux2;
int i=0; //Variable auxiliar para recorrer cadenas.
//Asignación de memoria a variables auxiliares.
Aux1 = malloc (sizeof (struct nodo) );
Aux2 = malloc (sizeof (struct nodo) );
Actual = malloc (sizeof (struct nodo) );
//Memoria asignada.
//Recorremos la lista desde su primer nodo.
Actual=Lista->Inicio;
while (Actual!=NULL) //Mientras no se llegue el final de la lista...
{
if (comparar (Actual->nombre,cadena1)==0) //Al ser 0, quiere decir que las cadenas son iguales.
{
Aux1=Actual; //Guarda el nodo hallado (actual) en un auxiliar.
break;
}
//Si no encontro el nodo que buscamos se mueve el siguiente nodo.
else Actual=Actual->Siguiente;
}
//Si el primer nodo fue encontrado...
if (Aux1!=NULL)
{
//Recorremos la lista desde su primer nodo.
Actual=Lista->Inicio;
while (Actual!=NULL) //Mientras no se llegue el final de la lista...
{
if (comparar (Actual->nombre,cadena2)==0) //Al ser 0, quiere decir que las cadenas son iguales.
{
Aux2=Actual; //Guarda todo el nodo hallado (actual) en un auxiliar.
break;
}
//Si no encontro el nodo que buscamos se mueve el siguiente nodo.
else Actual=Actual->Siguiente;
}
//Si el segundo nodo fue encontrado...
if (Aux2!=NULL)
{
//Si el primer nodo es el primer elemento...
if (Aux1==Lista->Inicio)
{
//Muevo el segundo nodo al inicio de la lista y al primer nodo a la posición
//donde se encontraba el segundo nodo.
Lista->Inicio=Aux2;
Aux2->Anterior->Siguiente=Aux1;
}
//Si el segundo nodo es el primer elemento...
else if (Aux2==Lista->Inicio)
{
//Muevo el primer nodo al inicio de la lista y al segundo nodo a la posición
//donde se encontraba el primer nodo.
Lista->Inicio=Aux1;
Aux1->Anterior->Siguiente=Aux2;
}
//Si ninguno de los dos nodos hallados es el primer elemento de la lista.
else
{
Aux2->Anterior->Siguiente=Aux1;
Aux1->Anterior->Siguiente=Aux2;
}
//Almaceno el puntero que apunta al nodo anterior del primer nodo en una variable
//temporal.
T1 = Aux1->Anterior;
//Muevo el puntero que apunta al nodo anterior del segundo nodo al primer nodo.
Aux1->Anterior = Aux2->Anterior;
//Almaceno el puntero que apunta al nodo siguiente del primer nodo en una variable
//temporal.
T2 = Aux1->Siguiente;
//Si el primer nodo no es el último elemento...
if (Aux1!=Lista->Fin)
Aux1->Siguiente->Anterior=Aux2;
//Si es el último elemento...
Aux1->Siguiente=Aux2->Siguiente;
//Muevo el puntero que apunta al nodo anterior del primer nodo al segundo nodo.
Aux2->Anterior = T1;
//Si el segundo nodo no es el último elemento...
if (Aux2==Lista->Fin)
Aux2->Siguiente->Anterior=Aux1;
//Si es el último elemento...
Aux2->Siguiente=T2;
}
return Lista->Inicio; //Retorna el lo apuntado por el inicio de la lista.
}
else return NULL; //Retorna NULL si uno de los nodos no fue encontrado.
}
//-------------------------------------ARRAY DE NODOS---------------------------------//
void *copiar(struct nodo *Lista, char letra)
{
struct nodo *Actual;
int i=0; //Variable auxiliar para recorrer el array de punteros.
char *p[Lista->tam]; //Array de punteros, almacena los nombres que empiecen con la
//letra ingresada por el usuario.
Actual=Lista->Inicio; //Parte desde el primer elemento de la lista.
printf("\n----->");
while (Actual!=NULL) //Mientras no llegue al final de la lista...
{
if (Actual->nombre[0] == letra) //Si la primera letra del nombre del nodo que se
//está analizando es igual a letra...
{
p[i]=Actual->nombre; //Se guarda el nombre del nodo en un array de punteros.
printf ("%s----->",p[i]); //Imprime dicho nombre.
i++; //Incrementa la posición del array de punteros en 1.
}
Actual=Actual->Siguiente; //Nos corremos al siguiente nodo.
}
}
Les adjunto el enunciado del parcial.
Saludos!