• Publicidad

Recorrido y búsqueda en C

Todo lo relacionado con lenguajes de programación distintos de Perl: PHP, Java, C++, Ruby, Python, etc.

Recorrido y búsqueda en C

Notapor gonzalos » 2012-11-14 10:54 @496

Hola a todos

Estoy intentando hacer un algoritmo en C, que me recorra una lista y busque aquellos valores por encima de 5.0.

El fichero de entrada sería de este estilo:

n id,nota,id nota...

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
3 1 1.0 2 3.0 3 5.0
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


El código que tengo hecho hasta ahora es

Sintáxis: [ Descargar ] [ Ocultar ]
Using c Syntax Highlighting
  1. #include <stdio.h>
  2. typedef enum { FALSE, TRUE } bool;
  3. int main() {
  4.     /* Declaración de variables */
  5.         float x, j;
  6.         int n, i, id;
  7.         bool encontrado;
  8.         j = 0.0;
  9.  
  10.         /* Pre: Lectura de los datos de entrada */
  11.         scanf( "%d", &n );                         /* leer nº de exámenes */
  12.         for ( i = 1; i <= n; i++ ) {
  13.             scanf( "%d", &id );                    /*leer identificador*/
  14.             scanf( "%f", &x );                     /*leer notas*/;
  15.         }
  16.         encontrado = FALSE;
  17.         while ( !( id >= n ) && !encontrado ) {
  18.             encontrado = ( x > 5.0 );              /*actualizar encontrado*/
  19.             if ( !encontrado ) {
  20.                 scanf( "%d", &x );                 /*saltar secuencia*/
  21.             }
  22.         }
  23.         if (encontrado) {
  24.             j = j + 1.0;       /*guardar todos los números mayores de 5.0*/ scanf( "%d", &x );
  25.         }
  26.  
  27.         printf( "%d\n", j );   /*pintar nº de valores mayores a 5.0*/
  28.  
  29.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


He estado revisando el algoritmo y soy incapaz de encontrar dónde está el error, ya que al ejecutar el mismo, el valor de j siempre me da 0.

¿Alguna idea?

Un saludo
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Publicidad

Re: Recorrido y búsqueda en C

Notapor explorer » 2012-11-14 19:55 @871

Aunque este es un foro de Perl, creo que puedo contestar ;)

Hay un bucle que lee los valores, pero ¿dónde los guarda?

Y si no los guarda... creo que alguna llave está mal puesta...

Esta es una versión sin almacenamiento de los datos (los vamos sacando a medida de que los vamos leyendo)
Sintáxis: [ Descargar ] [ Ocultar ]
Using c Syntax Highlighting
  1. /*
  2.     Encontrar valores mayores que cinco
  3.  
  4.     Joaquin Ferrero, 20121115
  5. */
  6.  
  7. #include <stdio.h>
  8.  
  9. void main(int argc, char * argv) {
  10.     int i;
  11.     int numero_examenes;
  12.     int id;
  13.     float nota;
  14.  
  15.     scanf("%d", &numero_examenes);
  16.     printf("Número de exámenes: [%d]\n", numero_examenes);
  17.  
  18.     for(i = 1; i <= numero_examenes; i++) {
  19.         int r = scanf("%d %f", &id, &nota);
  20.        
  21.         if (r != 2) {
  22.             printf("ERROR: no he podido leer la nota número %d\n", i);
  23.         }
  24.         else {
  25.             if (nota > 5.0) {
  26.                 printf("Aprobado: alumno %d: %.01f\n", id, nota);
  27.             }
  28.         }
  29.     }
  30. }
  31.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Lo compilamos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. explorer@casa:~/Documentos/Desarrollo> gcc -o mayor_5 mayor_5.c
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
y lo probamos
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. explorer@casa:~/Documentos/Desarrollo> echo "5 1 1.0 2 3.0 3 5.0 4 5.6 5 8.7" | ./mayor_5
  2. Número de exámenes: [5]
  3. Aprobado: alumno 4: 5.6
  4. Aprobado: alumno 5: 8.7
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Y esta es otra versión con almacenamiento (primero leemos toda la entrada y luego sacamos el resultado)
Sintáxis: [ Descargar ] [ Ocultar ]
Using c Syntax Highlighting
  1. /*
  2.     Encontrar valores mayores que cinco
  3.  
  4.     Joaquin Ferrero, 20121115
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9.  
  10. int   ids[80];    /* Array para los id       */
  11. float notas[80];  /* Lo mismo para las notas */
  12.  
  13. void main(int argc, char * argv) {
  14.     int i;
  15.     int numero_examenes;
  16.     int id;
  17.     float nota;
  18.  
  19.     scanf("%d", &numero_examenes);
  20.     printf("Número de exámenes: [%d]\n", numero_examenes);
  21.  
  22.     if (numero_examenes >= 80) {
  23.         printf("ERROR: No puedo procesar tantas notas. Máximo: 80\n");
  24.         exit(1);
  25.     }
  26.  
  27.     for(i = 1; i <= numero_examenes; i++) {
  28.         int r = scanf("%d %f", &id, &nota);
  29.        
  30.         if (r != 2) {
  31.             printf("ERROR: no he podido leer la nota número %d\n", i);
  32.         }
  33.         else {
  34.             /* guardamos los valores */
  35.             ids[i-1]   = id;
  36.             notas[i-1] = nota;
  37.         }
  38.     }
  39.  
  40.     /* Buscamos los valores que superen el corte */
  41.     for(i = 0; i < numero_examenes; i++) {
  42.         if (notas[i] > 5.0) {
  43.             printf("Aprobado: alumno %d: %.01f\n", ids[i], notas[i]);
  44.         }
  45.     }
  46. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El resultado es el mismo. Lo importante es ver el uso de los vectores y cómo los recorremos.

P.D. Hacía 10 años que no programaba en C... algo normal, porque entonces conocí Perl, y aprendí que este problema se podía resolver en una sola línea ;)
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. explorer@casa:~/Documentos/Desarrollo> echo "5 1 1.0 2 3.0 3 5.0 4 5.6 5 8.7" | perl -E '($n, %notas) = split " ", <>; say "Número de exámenes: [$n]"; for (keys %notas) { printf "Aprobado: alumno %d: %.01f\n", $_, $notas{$_} if $notas{$_} > 5.0 }'
  2. Número de exámenes: [5]
  3. Aprobado: alumno 4: 5.6
  4. Aprobado: alumno 5: 8.7
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Y he tardado mucho (pero que mucho) menos tiempo en resolverlo :lol:
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Recorrido y búsqueda en C

Notapor gonzalos » 2012-11-15 04:19 @222

Hola, explorer.

Muchas gracias por la respuesta. Yo también lo hubiera hecho en Perl, pero en el ejercicio hay que usar C obligatoriamente.

En principio había que hacerlo sin usar tuplas, ya que todavía no hemos llegado a ese tema, -en teoría- por lo que para resolverlo deberíamos usar un esquema de recorrido o un esquema combinado de recorrido y búsqueda aplicado a la entrada.

Una duda, ¿el resultado de la lectura no se guardaría en la variable &x?

Me surge la duda, porque cuando capturas del canal de entrada una serie de números para luego sumarlos, estos se almacenan en la variable que se usa para capturalos por pantalla y luego se enviarían a la variable suma.

¿Es así o estoy equivocado?

Un saludo
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Re: Recorrido y búsqueda en C

Notapor explorer » 2012-11-15 10:53 @495

Pues sí, estás equivocado :)

Si te declaras una variable como entera, solo almacenará un valor entero: el último que hayas leído o el último que le hayas asignado.

Por eso, en las dos soluciones, usamos las variables entera y flotante para leer los datos que nos van llegando del exterior, pero inmediatamente los procesamos (en el caso de la primera solución) o los almacenamos en los vectores (caso de la segunda solución).

Solo por el hecho de hacer un scanf("%d, &x) no implica que estás almacenando todos los valores, sino solo uno cada vez. Si no haces nada con el valor que has leído, en el siguiente ciclo del bucle, el siguiente entero que leas, sobreescribirá el valor leído antes.

Fíjate en mi primera pregunta del mensaje anterior: «Hay un bucle que lee los valores, pero ¿dónde los guarda?»
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Recorrido y búsqueda en C

Notapor gonzalos » 2012-11-16 03:35 @190

Hola, explorer.

Muchas gracias por la aclaración. Ahora voy a intentar dividir el programa e ir metiéndolo en módulos a ver si no tengo problemas al hacerlo.

Un saludo
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Re: Recorrido y búsqueda en C

Notapor gonzalos » 2012-11-16 05:11 @258

Bueno aquí va mi propuesta:

Sintáxis: [ Descargar ] [ Ocultar ]
Using c Syntax Highlighting
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define aprobado 5.0
  4.  
  5. void leerDatos( int numAlumnos, int idAlumno, float notaExamen, int aprobados );
  6. void salida( int aprobados, int numAlumnos );
  7.  
  8. int main() {
  9.  
  10.     int idAlumno;
  11.     int numAlumnos;
  12.     int alumnos;
  13.     float notaExamen;
  14.     int aprobados;
  15.     aprobados  = 0;
  16.     numAlumnos = 0;
  17.  
  18.     leerDatos( numAlumnos, idAlumno, notaExamen, aprobados );
  19.     salida( aprobados, numAlumnos );
  20.  
  21.     system("PAUSE");
  22.     return 0;
  23. }
  24.  
  25. void leerDatos( int numAlumnos, int idAlumno, float notaExamen, int aprobados ) {
  26.     int n;
  27.  
  28.     scanf( "%d", &numAlumnos );
  29.  
  30.     for ( n = 1; n <= numAlumnos; n++ ) {
  31.         scanf( "%d", &idAlumno );
  32.         scanf( "%f", &notaExamen );
  33.  
  34.         if ( notaExamen >= aprobado ) {
  35.             aprobados = aprobados + 1;
  36.         }
  37.     }
  38. }
  39.  
  40. void salida( int aprobados, int numAlumnos ) {
  41.     if ( aprobados > ( numAlumnos / 2 ) ) {
  42.         printf("A");
  43.     }
  44.     else {
  45.         printf("S");
  46.     }
  47. }
  48.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No sé a qué es debido, pero no captura los datos en algún punto de la 1ª acción.

Un saludo
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Re: Recorrido y búsqueda en C

Notapor explorer » 2012-11-16 12:35 @566

La función salida() la estás llamando siempre con los valores 0 y 0.

Estás llamando a leerDatos() con variables pasadas por valor, no por referencia, y así no puedes obtener el valor leído fuera de la función.

Debes reescribir la función para pasarle las direcciones de las variables, no los valores de las variables.

Más información en el capítulo 5.2 del libro The C Programming Language, de Kernighan y Ritchie.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Recorrido y búsqueda en C

Notapor gonzalos » 2012-11-17 15:00 @667

Hola, explorer.

Muchas gracias por la ayuda, todavía ando bastante verde con los punteros, las direcciones, el paso de variables por valor y por referencia.

Una última cosa, al modular el algoritmo, el compilador me indica que debería inicializar ciertas variables, que no son constantes, y que no era necesario inicializar antes de transformar el algortimo en una sucesión de funciones.

¿A qué sería debido esto?

Un saludo
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283

Re: Recorrido y búsqueda en C

Notapor explorer » 2012-11-17 16:42 @737

Como es un proyecto pequeño, puedes resolverlo fácilmente con variables globales, y así no tienes que pasar argumentos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Recorrido y búsqueda en C

Notapor gonzalos » 2012-11-19 09:54 @454

Hola, explorer

Perfecto, muchas gracias

Un saludo,
Gonzalo
gonzalos
Perlero nuevo
Perlero nuevo
 
Mensajes: 77
Registrado: 2009-11-27 05:47 @283


Volver a Programación en general

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 18 invitados