Ver Mensaje Individual
  #1  
Antiguo 01-12-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Reputación: 14
aguml Va por buen camino
Otra forma que se me ocurrio de ordenar una lista simple:

Código PHP:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE_MAX_PALABRA 30
#define SIZE_MAX_ALFABETO 27
//-----------------------------------------------------------------------------
/* DEFINICION DE TIPOS */
typedef struct ElementoLista
{
  
char *palabra;
  
int indice;
  
struct ElementoLista *sig;
}
Elemento;

typedef struct ListaIdentificar {
   
Elemento *inicio;
   
Elemento *fin;
   
int nElementos;
}
Lista;
//-----------------------------------------------------------------------------

/* PROTOTIPOS DE FUNCIONES */
void Inicializacion (Lista *lista);
int InsertarEnLista (Lista *listaElemento actualchar *palabraint indice);
int Sup_en_lista (Lista *listaint pos);
int Sup_inicio (Lista *lista);
void DestruirLista (Lista *lista);
void Imprimir (Lista *lista);
void PreguntarPalabras(Lista *listaint nPalabras);
int Menu(void);
void Jugar(void);
int OrdenarLista(Lista *lista);
void LimpiarCadena(char *cadenaint size);
void PasarAMayusculas(char *cadenaint size);
void ActualizarLetrasIntroducidas(char *cadenaint sizechar caracter);
int ActualizarLetrasRestantes(char *cadenaint sizechar caracter);
int ActualizarMascara(char *mascarachar *palabraint sizechar caracter);
int LlenarLista(FILE *archivoLista *lista);
//-----------------------------------------------------------------------------

int main()
{
   
int retval;

   do{
      
retval Menu();

      switch(
retval)
      {
         case 
1:
            
Jugar();
            break;
      }
   }while(
retval != 0);

   return(
0);
}
//-----------------------------------------------------------------------------

void Inicializacion (Lista *lista)
{
   
lista->inicio=NULL;
   
lista->fin=NULL;
   
lista->nElementos=0;
}
//-----------------------------------------------------------------------------

/*inserción en la lista */
int InsertarEnLista (Lista *listaElemento *actualchar *palabraint indice)
{
   
Elemento *nuevo_elemento;

   if ((
nuevo_elemento = (Elemento *) malloc (sizeof (Elemento))) == NULL)
      return -
1;

   if ((
nuevo_elemento->palabra = (char *) malloc (SIZE_MAX_PALABRA sizeof (char))) == NULL)
      return -
1;

   
strcpy (nuevo_elemento->palabrapalabra);
   
nuevo_elemento->indice indice;

   if(
actual != NULL)
      
actual->sig nuevo_elemento;
   
nuevo_elemento->sig NULL;

   if(
lista->inicio == NULL)
      
lista->inicio nuevo_elemento;
   
lista->fin nuevo_elemento;
   
lista->nElementos++;
   return 
0;
}
//-----------------------------------------------------------------------------

/* eliminar un elemento después de la posición solicitada */
int Sup_en_lista (Lista listaint pos)
{
   
int i;
   
Elemento *actual;
   
Elemento *sup_elemento;

   if (
lista->nElementos <= || pos || pos >= lista->nElementos)
      return -
1;

   
actual lista->inicio;
   for (
1pos; ++i)
      
actual actual->sig;
   
sup_elemento actual->sig;
   
actual->sig actual->sig->sig;
   if(
actual->sig == NULL)
      
lista->fin actual;
   
free (sup_elemento->palabra);
   
free (sup_elemento);
   
lista->nElementos--;
   return 
0;
}
//-----------------------------------------------------------------------------

/* eliminación al inicio de la lista */
int Sup_inicio (Lista *lista)
{
   
Elemento *sup_elemento;

   if (
lista->nElementos == 0)
      return -
1;
   
sup_elemento lista->inicio;
   
lista->inicio lista->inicio->sig;

   if (
lista->nElementos == 1)
      
lista->fin NULL;
   
free (sup_elemento->palabra);
   
free (sup_elemento);
   
lista->nElementos--;
   return 
0;
}
//-----------------------------------------------------------------------------

/* destruir la lista */
void DestruirLista (Lista *lista)
{
   while (
lista->nElementos 0)
      
Sup_inicio (lista);
}
//-----------------------------------------------------------------------------

/* visualización de la lista */
void Imprimir (Lista *lista)
{
   
Elemento *actual;

   
actual lista->inicio;
   while (
actual != NULL){
      
printf ("%s\n"actual->palabra);
      
actual actual->sig;
   }
}
//-----------------------------------------------------------------------------

void LimpiarCadena(char *cadenaint size)
{
   
int indice;

   for(
indice 0indice sizecadena[indice++] = '\0');
}
//-----------------------------------------------------------------------------

void PasarAMayusculas(char *cadenaint size)
{
   
int indice;

   for(
indice=0indice size;indice++)
   {
      if(
cadena[indice] >= 'a' && cadena[indice] <= 'z')
         
cadena[indice] -= 32;
   }
}
//-----------------------------------------------------------------------------

int ActualizarLetrasRestantes(char *cadenaint sizechar caracter)
{
   
int indicej;
   
char *aux;

   if ((
aux = (char *) malloc ((size) * sizeof (char))) == NULL)
      return -
1;

   
//Buscamos el caracter introducido en el array con los caracteres restantes
   //Si lo encuentra lo omite y si es otro lo copia a un array auxiliar
   
for(indice=0,j=0indice size;indice++)
   {
      if(
cadena[indice] != caracter)
      {
         
aux[j]=cadena[indice];
         
j++;
      }
   }

   
//Si se encontró j será menor que indice con lo que finalizo la cadena auxiliar y
   //copio el contenido de la variable auxiliar a la cadena a mostrar con los
   //caracteres restantes
   
if(indice)
   {
      
aux[j] = '\0';
      
strcpy(cadenaaux);
   }
   
free(aux);

   return 
0;
}
//-----------------------------------------------------------------------------

void ActualizarLetrasIntroducidas(char *cadenaint sizechar caracter)
{
   
int indice;

   
//Recorro los caracteres introducidos en busca del nuevo caracter
   
for(indice=0indice sizeindice++)
      if(
cadena[indice] == caracter){
         break;
      }

   
//Si se ha introducido un nuevo caracter y no está en la lista
   //le añado el nuevo caracter
   
if(size == indice)
      
cadena[size] = caracter;
}
//-----------------------------------------------------------------------------

int ActualizarMascara(char *mascarachar *palabraint sizechar caracter)
{
   
int indiceaciertos=0encontrada=0;

   for(
indice=0indice size && size != 0indice++)
      if(
mascara[indice] == caracter)
         
encontrada++;

   if(
encontrada 0){
      
aciertos=0;
   }else{
      
//Busco el caracter introducido en la palabra y si se encuentra lo quito de la palabra
      
for(indice=0indice size && size != 0indice++)
      {
         if(
palabra[indice] == caracter)
         {
            
mascara[indice] = palabra[indice];
            
aciertos++;
         }
      }
   }
   return 
aciertos;
}
//-----------------------------------------------------------------------------

void PreguntarPalabras(Lista *listaint nPalabras){
   const 
char letrasValidas[SIZE_MAX_ALFABETO] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   
int vidas 5indicelargoPalabralargoIntroducidaslargoRestantesaciertos;
   
int contador=0encontradossalir 0;
   
char palabra[SIZE_MAX_PALABRA], auxPalabra[SIZE_MAX_PALABRA];
   
char letrasIntroducidas[SIZE_MAX_ALFABETO], letrasRestantes[SIZE_MAX_ALFABETO];
   
char caracter;
   
Elemento *actual lista->inicio;

   do{
      
//Limpio los 3 arrays (Se puede usar en su lugar memset)
      
LimpiarCadena(letrasRestantes,SIZE_MAX_ALFABETO);
      
LimpiarCadena(letrasIntroducidas,SIZE_MAX_ALFABETO);
      
LimpiarCadena(auxPalabra,SIZE_MAX_PALABRA);

      
//Inicializo las variables que se necesiten
      
strcpy(letrasRestantes,letrasValidas);
      
strcpy(palabra,actual->palabra);
      
largoPalabra strlen(palabra);
      
encontrados 0;

      
//Si hay algun caracter en minusculas en la palabra lo paso a mayusculas
      
PasarAMayusculas(palabra,largoPalabra);

      
//Muestro la mascara para que se vea cuantos caracteres tiene (Se puede hacer con memset)
      
for(indice=0indice largoPalabra;indice++)
      {
         
auxPalabra[indice] = '-';
      }

      
//Mientras no lleguemos al final de la lista y tengamos vidas seguimos
      
while (actual != NULL && vidas 0){
         do{ 
//Este bucle es para descartar todos los caracteres no permitidos
            //Muestro la informacion
            
system("CLS");
            
printf("\n%c: %d"3vidas);
            
printf("\nLetras introducidas: %s",letrasIntroducidas);
            
printf("\nLetras restantes: %s",letrasRestantes);
            
printf("\nNumero de palabras solucionadas: %d",contador);
            
printf("\n%s\n\n",auxPalabra);
            
printf("Introduce una letra (0 para salir): ");
            
fflush(stdin); //limpio el flujo de entrada
            
caracter getchar(); //Pido el caracter

            //Si el caracter introducido esta en minusculas lo paso a mayusculas
            
PasarAMayusculas(&caracter,1);

         }while((
caracter 'A' || caracter 'Z') && caracter != '0');

         
//Si se introdujo 0 salimos del juego
         
if(caracter == '0')
         {
            
salir=1;
            
printf("\n\nSalida forzada por el usuario.\n\n");
            break;
         }

         
largoRestantes strlen(letrasRestantes);

         
ActualizarLetrasRestantes(letrasRestantes,largoRestantescaracter);

         
//Busco el caracter introducido en la palabra y si se encuentra lo quito de la palabra
         
encontrados += aciertos ActualizarMascara(auxPalabrapalabralargoPalabracaracter);

         
//Si se ha encontrado el caracter le resto el numero de caracteres encontrados
         //al largo de la palabra e inicializo la variable de encontrados
         //Si no se encuentra resto una vida
         
if(aciertos == 0){
            
vidas--;
         }

         
largoIntroducidas strlen(letrasIntroducidas);

         
ActualizarLetrasIntroducidas(letrasIntroducidas,largoIntroducidascaracter);

         
//Si el largo de la palabra es 0 es porque ya se metieron todos
         //los caracteres de dicha palabra asi que la muestro y obtengo
         //la siguiente palabra
         
if(largoPalabra == encontrados){
            
contador++;
            
system("CLS");
            
printf("\n%c: %d"3vidas);
            
printf("\nLetras introducidas: %s",letrasIntroducidas);
            
printf("\nLetras restantes: %s",letrasRestantes);
            
printf("\nNumero de palabras solucionadas: %d",contador);
            
printf ("\n\n%s    Solucionada!!!\n\n"palabra);
            
actual actual->sig;
            
system("PAUSE");
            break;
         }

         
//Si no hay vidas hemos perdido asi que lo indico y salimos
         
if(vidas == 0)
         {
            
salir 1;
            
system("CLS");
            
printf("\n%c: %d"3vidas);
            
printf("\nLetras introducidas: %s",letrasIntroducidas);
            
printf("\nLetras restantes: %s",letrasRestantes);
            
printf("\nNumero de palabras solucionadas: %d",contador);
            
printf("\n\nPartida finalizada.\n\n");
         }
      }

      
//Si son iguales es porque ya solucionamos todas las palabras
      //solicitadas asi que hemos ganado
      
if(nPalabras == contador)
      {
         
printf("\n\nHas ganado.\n\n");
         
salir 1;
      }
   }while(
salir != 1);
}
//-----------------------------------------------------------------------------

//Ordena el contenido de la lista
int OrdenarLista(Lista *lista)
{
   
int j,pos,retval;
   
Elemento *actual,*menor;
   
Lista *listaAux;

   if(
lista->nElementos 1){
      
//Reservo memoria para la lista auxiliar que usaré para ordenar la lista
      
if ((listaAux = (Lista *) malloc (sizeof (Lista))) == NULL){
         
retval = -1//Valor de retorno que indica que no se pudo obtener suficiente memoria
      
}else{
         
//Inicializo la lista auxiliar
         
Inicializacion(listaAux);

         
//Mientras que el número de elementos sea mayor que 1...
         
while(lista->nElementos 1){
            
menor lista->inicio//le asigno al puntero de tipo Elemento la direccion de inicio de la lista
            
pos=0//inicializo la variable para saber la posicion del elemento anterior al de menor indice

            //Recorro todos los elementos en busca del que tenga menor indice
            
for (j=1actual=lista->iniciolista->nElementosj++, actual=actual->sig)
            {
               
//Si el indice del actual es mayor que el del siguiente...
               
if(menor->indice actual->sig->indice){
                  
menor actual->sig//Asigno a menor la direccion del elemento siguiente
                  
pos j//Asigno a pos la posicion del elemento anterior al que tiene el indice menor
               
}
            }
            
//Inserto el elemento menor en la lista auxiliar
            
InsertarEnLista(listaAuxlistaAux->finmenor->palabramenor->indice);

            if(
pos==0){ //Si pos es 0 es porque es el primer elemento de la lista
               
Sup_inicio(lista); //Elimino al primer elemento de la lista
            
}else{ //Si pos es diferente de 0...
               
Sup_en_lista(lista,pos); //Elimino el elemento que está despues de la posicion pos
            
}
         }

         if(
lista->nElementos == 1){ //Si hay un solo elemento en la lista...
            //Inserto ese elemento en la lista auxiliar ya que es el último que falta por ordenar y el que tiene mayor indice
            
InsertarEnLista(listaAuxlistaAux->finlista->inicio->palabralista->inicio->indice);
            
Sup_inicio(lista); //Elimino el elemento que queda para limpiar la lista
         
}

         
//Recorro la lista auxiliar para rellenar la lista
         
for(j=0actual=listaAux->iniciolistaAux->nElementosj++, actual=actual->sig)
            
InsertarEnLista(listalista->finactual->palabraactual->indice);

         
DestruirLista(listaAux); //Libero la memoria de los elementos de la lista auxiliar
         
free(listaAux); //Libero la memoria de la lista auxiliar
         
retval=0//Valor de retorno que indica que todo fue bien
      
}
   }else{
      
retval = -2//Valor de retorno que indica que el numero de elementos de la lista no es correcto
   
}
   return 
retval;
}
//-----------------------------------------------------------------------------

int LlenarLista(FILE *archivoLista *lista)
{
   
int finLectura=0,j,indice,contador;
   
char caracter,palabra[SIZE_MAX_PALABRA];

   
contador 0;
   
j=0;

   while( 
finLectura != 1)
   {
      
LimpiarCadena(palabraSIZE_MAX_PALABRA);

      while (!
feof(archivo)){
         do{
            
caracter=fgetc(archivo);
         }while(
caracter=='\n');

         if (
caracter!=';'){
            
palabra[j]=caracter;
            
j++;
         }else{
            
j=0;

            
//FGETC NO SIRVE YA QUE SOLO CAPTURA UN CARACTER
            //¿Y SI EL NUMERO ES POR EJEMPLO 10, O 150, O CUALQUIER OTRO QUE TENGA UN 1 DELANTE?
            
fscanf(archivo,"%d",&indice);

            if(
InsertarEnLista(lista,lista->finpalabraindice) == -1){
               
printf("\nError al insertar un elemento a la lista. Pulsa intro para salir.\n\n");
               
system("PAUSE");
               return -
1;
            }
            
contador++;

            
LimpiarCadena(palabra,SIZE_MAX_PALABRA);
         }
      }
      
finLectura++;
   }
   return 
contador;
}
//-----------------------------------------------------------------------------

//Version ordenando la lista despues de haberla obtenido entera desordenada
void Jugar(){
   
int cantidad,error,contador;
   
char caracter;
   
Lista *lista;
   
FILE *archivo;
   
   if ((
lista = (Lista *) malloc (sizeof (Lista))) != NULL){
      
Inicializacion(lista);
      do{
         
system ("color b");
         
system("cls");
         
printf("\n\t\t\t  ¿Con cuantas palabras desea jugar? ");
         
scanf("%d",&cantidad);
         if(
cantidad || cantidad 10){
            
error 1;
            
printf("\nTiene que ser un valor comprendido entre 3 y 10\n");
            
system("PAUSE");
         }else{
            
error 0;
         }
      }while(
error==1);

      
archivofopen("prueba.txt","r");

      if (
archivo== NULL){
         
printf("El archivo no se encuentra");
      }else{
         
//Lleno la lista con todas las palabras del archivo indicado
         
contador LlenarLista(archivolista);

         
fclose(archivo);

         
//Si se obtuvieron el numero de palabras indicadas...
         
if(contador >= cantidad)
         {
            
OrdenarLista(lista);
            
PreguntarPalabras(listacantidad);
            
system("PAUSE");
            
system("CLS");

            
//Imprimimos la lista de palabras
            
printf("\nLista de palabras:");
            
printf("\n-----------------\n\n");
            
Imprimir(lista);
         }else{
            
printf("\nHay menos palabras en el archivo que las deseadas\n\n");
         }
      }
      
DestruirLista(lista);
      
free(lista);
   }
   
printf("\n");
   
system("PAUSE");
}
//-----------------------------------------------------------------------------

int Menu()
{
   
char resp;

   
system ("color b");
   
system("cls");
   
printf("\n\n\t\t\t* * * * * MENU DE OPCIONES * * * * *");
   
printf("\n\t\t---------------------------------------------------");
   
printf("\n\t\t\t  Juego de el ahorcado ");
   
printf("\n\t\t---------------------------------------------------\n\n\n\n");
   
printf("\t\t\t\t (1) Jugar \n");
   
printf("\t\t\t\t (0) salir\n\n");
   
printf("\t\t\t\t Opcion: ");

   
resp=getchar();

   return (
resp 48); //Devuelvo su valor entero
}
//----------------------------------------------------------------------------- 
Utilizo una lista auxiliar en la cual guardo los elementos ya ordenados y los voy eliminando de la lista principal. Luego copio todo ya ordenado en la lista principal y libero la memoria ocupada por la lista auxiliar.
Si consigues un método mejor compartelo aquí por favor, estoy interesado ya que nunca se me ocurrio ordenar una lista enlazada y he visto que es algo complejo de hacer.
Responder Con Cita