Ejercicio en C

Iniciado por ElpIOLA20, 10 Agosto 2018, 01:33 AM

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

ElpIOLA20

Hola a todos! Estoy comenzando a estudiar programación. Y necesito ayuda con un ejercicio. La verdad es que ya intente de varias formas y no me sale. Quisiera por lo menos alguna pista. Seguramente ustedes sabrán alguna manera de hacerlo.
El ejercicio es el siguiente:

Tengo un archivo. Lo parseo, osea lo leo y lo guardo en un ArrayList. Hasta acá todo bien. El archivo contiene caracteres. Osea 'a', 'b', 'z', '4' etc.
El ejercicio me pide que haga una lista con todos los caracteres que tengo en el arraylist de manera ascendente y que aparezcan una ves cada uno. (porque hay varios caracteres que se repiten). El problema es que no se me ocurre como hacer una función que me los liste sin que se repitan.

ArrayList* listaOrdenadaAscendente(ArrayList* this, ArrayList* this2)
{
   int i;
   int len = al_len(this);
   eCaracter* letra;
   if(this != NULL && this2 != NULL)
   {
       for(i=0;i<len;i++)
       {
           letra = (eCaracter*) al_get(this,i); //asignamos los elementos del arraylist a la estructura,
           if(comprobarSiEsRepetida(this2,letra) == 1)
           {
               al_add(this2,letra); //agregamos los elementos a la nueva lista que van asignados los caracteres sin repetir.
           }
           else
           {
               al_remove(this2,i); //si ya existe el caracter lo elimino
           }
       }
   }
   return this2;
}

int comprobarSiEsRepetida(ArrayList* this, eCaracter* letra)
{
   int i, index = -1;
   eCaracter* aux;
   int len = al_len(this);
   if(this != NULL && letra != NULL)
   {
       for(i=0;i<len;i++)
       {
           aux = (eCaracter*) al_get(this,i);
           if(get_Caracter(aux) == get_Caracter(letra)) //Comparamos si son iguales
           {
               index = 0;
               break;
           }
           else
           {
               index = 1;
               break;
           }
       }
   }
   return index;
}


Gracias por su tiempo!

CalgaryCorpus

El ciclo for al interior de la funcion comprobarSiEsRepetida no parece tener oportunidades de repetirse muchas veces dado que el if-else siempre hace break, tanto si la condicion del if es verdadera o es falsa.

Me da la impresion que no quieres tener un else ahi y solo salir del for y de la funcion si una condicion ocurre y seguir en el loop si aun no se presenta.

Tampoco entiendo muy bien el ciclo for de la funcion listaOrdenadaAscendente. AL parecer quieres insertar en this2 si no se ha visto antes y eliminarlo si lo has visto antes. Es raro esto, porque no solo insertas si no lo has visto, y si lo has visto simplemente lo ignoras, en vez de intentar borrarlo?

Te sugiero usar nombres de variables que sirvan para entender mejor el programa, this y this2 no son los mejores nombres, especialmente si este codigo llegase a ser compilador por un compilador de C++.
Aqui mi perfil en LinkedIn, invitame un cafe aqui

ElpIOLA20

#2
Hola CalgaryCorpus gracias por responder. Leí lo que pusiste y si note que el else estaba de mas. Y que no estaba tan entendible para la gente que lo ve de afuera. Lo retoque un poco el código. Pero aun sigue sin funcionar.

ArrayList* listaOrdenadaAscendente(ArrayList* ListaVieja, ArrayList* ListaNueva)
{
   int i;
   int len = al_len(ListaVieja);
   eCaracter* letra;
   if(ListaVieja != NULL && ListaNueva != NULL)
   {
       for(i=0;i<len;i++)
       {
           letra = (eCaracter*) al_get(ListaVieja,i); //Agregamos los datos de la lista vieja al auxiliar letra.
           if(comprobarSiEsRepetida(ListaNueva,letra) == 1) //si la funcion devuelve 1 significa que no existe el elemento en la lista nueva.
           {
               al_add(ListaNueva,letra); // Por lo tanto aca lo agregamos a la nueva lista.
           }
       }
   }
   return ListaNueva;
}

int comprobarSiEsRepetida(ArrayList* ListaNueva, eCaracter* letra) //letra auxiliar de la vieja lista
{
   int i, index = -1;
   eCaracter* aux;
   int len = al_len(ListaNueva);
   if(ListaNueva != NULL && letra != NULL)
   {
       for(i=0;i<len;i++)
       {
           index = 1;
           aux = (eCaracter*) al_get(ListaNueva,i); // Agregamos los datos de la nueva lista al auxiliar.
           if(get_Caracter(aux) == get_Caracter(letra)) // Comparamos si los datos del auxiliar de la nueva lista son iguales al de la vieja lista.
           {
               index = 0;
               break;
           }
       }
   }
   return index;
}

CalgaryCorpus

Te sugiero ser mas explicito en que problemas tienes. Decir que no funciona no da mucha informacion.
Decir que los datos se duplican, o que tal linea hace que el programa caiga, explicitando como estas probando, cuales son las entradas y las salidas que hacen evidente el problema da a entender el trabajo que estas poniendo y ayuda a ayudarte.

Tambien : Usa las etiquetas Geshi adecuadas para que la sintaxis sea coloreada mejor.
Aqui mi perfil en LinkedIn, invitame un cafe aqui

ElpIOLA20

#4
CalgaryCorpus a continuación explicare detalladamente.
Este programa lee un archivo .csv el cual contiene caracteres. Yo a través de otras funciones lo parseo(leo el archivo y guardo los datos en un ArrayList).
Este ArrayList ya esta declarado y inicializado en el main.c.

ArrayList* listaVieja;
   listaVieja= al_newArrayList(); //Esta funcion reserva memoria.


Una ves hecho esto, me pide que liste todos los caracteres de manera ascendente sin que se repitan.

Entonces yo pensé declarar otro ArrayList en el main.c el cual seria:

ArrayList* ListaNueva;
   ListaNueva= al_newArrayList();


Y en este guardar los caracteres sin repetir de manera ascendente...

A continuación declaro la función ArrayList* listaOrdenadaAscendente(ArrayList* ListaVieja, ArrayList* ListaNueva);

El cual se le pasan por parametros nuestros dos ArrayList(La que contiene los caracteres "ListaVieja" y la que va a guardar los nuevos caracteres sin repetir y de manera ascendente "ListaNueva").

Una ves declarada, procedo a desarrollar la función.

ArrayList* listaOrdenadaAscendente(ArrayList* ListaVieja, ArrayList* ListaNueva)
{
   int i;
   int len = al_len(ListaVieja); //al_len me devuelve el tamaño de ListaVieja.
   eCaracter* letra; //Declaramos un puntero al tipo de dato eCaracter* que es una estructura.
                   //La cual usaremos como un auxiliar para que guarde la direccion de memoria de nuestros elementos que se encuentran en nuestra ListaVieja
   if(ListaVieja != NULL && ListaNueva != NULL) //Verificamos que nuestras listas no sean NULL
   {
       for(i=0;i<len;i++)
       {
           letra = (eCaracter*) al_get(ListaVieja,i); //Agregamos los datos de ListaVieja al auxiliar letra.
           if(comprobarSiEsRepetida(ListaNueva,letra) == 1) //Invocamos nuestra funcion comprobarSiEsRepetida que funciona como un filtro. Le pasamos la ListaNueva y el auxiliar.
                                                     //Si devuelve 1 significa que no existe ningun elemento letra que sea igual a un elemento de la ListaNueva.
           {
               al_add(ListaNueva,letra); //Por lo tanto sino existe lo agregamos. al_add copia el elemento letra y lo agrega a la ListaNueva.
           }
       }
   }
   return ListaNueva;
}


Aparte desarrolle la funcion: int comprobarSiEsRepetida(ArrayList* ListaNueva, eCaracter* letra)

Que es invocada anteriormente. Esta funcion recibe un puntero a la ListaNueva y un puntero al elemento que quiero verificar si existe en la ListaNueva.

int comprobarSiEsRepetida(ArrayList* ListaNueva, eCaracter* letra)
   int i, index = -1;
   eCaracter* aux; //Declaramos un auxiliar de tipo eCaracter* para guardar los elementos que contiene la ListaNueva.
   int len = al_len(ListaNueva); //Esta funcion nos devuelve el tamaño de len
   if(ListaNueva != NULL && letra != NULL)
   {
       for(i=0;i<len;i++)
       {
           index = 1;
           aux = (eCaracter*) al_get(ListaNueva,i); // Agregamos los datos de la nueva lista al auxiliar.
           if(get_Caracter(aux) == get_Caracter(letra)) // Comparamos si los datos del auxiliar de la nueva lista son iguales al de la vieja lista.
           {
               index = 0;
               break;
           }
       }
   }
   return index; //Si retorna 1 no existe el elemento. Si retorna 0 existe.
}


Aparte de todo esto tengo declarado unas funciones que se que andan lo mas bien que sirven para mostrar elementos por pantalla. Entonces corro el programa y no me salta ningún error. Cuando eligo la opcion que me cargue la listaNueva de manera ascendente y sin caracteres. Directamente no me muestra nada. No cuelga el programa. Solamente no me muestra nada. Como si no estuvieran guardando los datos en la nueva lista.

Perdonen por tanto quilombo. Soy nuevo en esto y trato de explicar lo mejor que puedo. Gracias por su tiempo!

MAFUS

Estás reescribiendo muchas funciones que ya existen en la biblioteca estándar.

CalgaryCorpus

Sospecho que tu función al_add no está haciendo lo que esperas. Si tienes alguna función para espiar el contenido de una lista, hazlo justo después de llamar a al_add. Creo que obtendrás una lista vacía.

Si pruebas y confirmas mi sospecha, tal vez te conviene compartir el código de esa función también.
Aqui mi perfil en LinkedIn, invitame un cafe aqui

MAFUS

Podrías poner todo el código, así podríamos ver que es al estructura eCaracter y las demás funciones auxiliares.