Problema en C [Ayuda]

Iniciado por cacacolass, 28 Abril 2014, 15:33 PM

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

cacacolass

/*
* Dado vector de números enteros, obtener el promedio del mismo.
* Luego partir el vector en 2 vectores,
* donde los menores al promedio estén en un vector y los mayores en otro vector.
*/



#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void menmay (int vector[10], int i, double promedio);
void free (void* ptr);

int main(int argc, char **argv)
{
int vector[10];
int i;
double suma, promedio=0;

srand(time(NULL));
for (i=0; i<10; i++)
{
vector[i] = rand() % 100;
printf("%3d", vector[i]);
suma += vector[i];
}

promedio = suma/10;
printf("\n Suma de los valores del vector: %.0lf", suma);
printf("\n Promedio de los valores del vector: %.0lf", promedio);
printf("\n");
menmay(vector,i,promedio);
return 0;
}

void menmay (int vector[10], int i, double promedio)
{
int* menores;
int* mayores;
int j=0,k=0;

menores = (int*)malloc (10*sizeof(int));
mayores = (int*)malloc (10*sizeof(int));


for (i=0; i<10; i++)
{
if (vector[i] < promedio)
{
menores[j] = vector[i];
j++;
}

else
{
mayores[k] = vector[i];
   k++;
}

}
printf("Valores menores al promedio \n");
for (j=0;j<10;j++)
if (menores[j] != 0)
printf("%3d",menores[j]);

free(menores);

printf("\nValores mayores al promedio \n");
for (k=0;k<10;k++);
printf("%3d",mayores[k]);

free(mayores);
}

void free (void* ptr);


Los números menores funcionan correctamente, pero los números mayores al promedio siempre quedan en 0, por qué?

Muchas gracias. Saludos

eferion

#1
"suma" no está inicializado,

double suma, promedio=0;

luego el resultado al final del bucle es aleatorio:

 for (i=0; i<10; i++)
 {
   vector[i] = rand() % 100;
   printf("%3d", vector[i]);
   suma += vector[i];
 }


en consecuencia, la operación que usas para calcular el promedio te arroja un resultado incorrecto:

 promedio = suma/10;

solucionando esto el promedio te sale bien... pero aún verás valores extraños en la lista de resultados.

Esto es porque SIEMPRE imprimes los 10 valores de cada vector "menores y mayores"... y eso no es así. Si hay 3 números por debajo del promedio se deberían imprimir únicamente esos 3 valores.

Otra cosa... ¿por qué pasas 'i' como argumento de 'menmay'? No tiene ningún sentido y la función no necesita ese argumento para nada.

Y si te fijas en esta línea, verás algo raro:

  printf("\nValores mayores al promedio \n");
 for (k=0;k<10;k++); // <<<< EN ESTA
 printf("%3d",mayores[k]);


Si el bucle lo terminas con punto y coma... no hace nada.

Con los cambios propuestos al menos obtienes la lista de elementos... ahora tienes que evitar mostrar siempre 10 resultados para la lista de 'menores' y 'mayores':


60 68 25 17 96 99 67 26 48  5
Suma de los valores del vector: 511
Promedio de los valores del vector: 51
Valores menores al promedio
25  17  26  48   5 1027951689 1348221507 1919381362 1631874401 1090543988
Valores mayores al promedio
60  68  96  99  67 1867668577 1852403041 1329791079 1313819981 1196380752


nuevo: En la salida que te he puesto he separado los números por un espacio... te lo digo por si ves que tu salida no coincide con la mía (los números aleatorios no cuentan).

Blaster

#2
Para evitar el problema de siempre imprimir los diez valores de cada vector podrias usar una bandera en cada situación, que te indique cuantos son menores o mayores al promedio, tal que quede asi

Código (cpp) [Seleccionar]
for (i = 0; i < 10; i++){
   if (vector[i] < promedio){
    menores[j] = vector[i];
    cant1++, j++;
   }
   else{
     mayores[k] = vector[i];
     cant2++, k++;
    }
}
    printf("Valores menores al promedio \n");
    for (j = 0; j < cant1; j++)
if (menores[j] != 0)
printf("%d ", menores[j]);

    free(menores);

    printf("\nValores mayores al promedio \n");
    for (k = 0; k < cant2; k++)
printf("%d ", mayores[k]);

    free(mayores);


No olvides inicializar las banderas a cero

Saludos..

eferion

Cita de: Blaster en 28 Abril 2014, 17:06 PM
Para evitar el problema de siempre imprimir los diez valores de cada vector podrias usar una bandera en cada situación, que te indique cuantos son menores o mayores al promedio, tal que quede asi

Código (cpp) [Seleccionar]
for (i = 0; i < 10; i++){
       if (vector[i] < promedio){
          menores[j] = vector[i];
          cant1++, j++;
        }
       else{
          mayores[k] = vector[i];
          cant2++, k++;
}
}
printf("Valores menores al promedio \n");
for (j = 0; j < cant1; j++)
   if (menores[j] != 0)
      printf("%d ", menores[j]);

free(menores);

printf("\nValores mayores al promedio \n");
for (k = 0; k < cant2; k++)
   printf("%d ", mayores[k]);

free(mayores);


Saludos..

Después del primer for, cant1==j y cant2==k... para qué repetir valores?


for (i = 0; i < 10; i++){
  if (vector[i] < promedio){
    menores[j] = vector[i];
    j++;
  }
  else{
    mayores[k] = vector[i];
    k++;
  }
}

printf("Valores menores al promedio \n");
for (i = 0; i < j; i++)
  if (menores[i] != 0)
    printf("%d ", menores[i]);

free(menores);

printf("\nValores mayores al promedio \n");
for (i = 0; i < k; i++)
  printf("%d ", mayores[i]);

free(mayores);


Aunque también te digo que hay que dejar pensar un poco al que tiene los errores... si se lo das todo mascado a la primera no le vas a dar alicientes para que aprenda.

Blaster

Cita de: eferion en 28 Abril 2014, 17:11 PM
Después del primer for, cant1==j y cant2==k... para qué repetir valores?

Muy cierto no me habia fijado :rolleyes:

Saludos..

leosansan


Lo que no tiene ningún sentido es pasarle a la función "i" ya que no aporta ninguna información a la misma. Bastaría declarar int i en la función menmay y dejarla así:

Código (cpp) [Seleccionar]
void menmay (int vector[10], double promedio);

Código (cpp) [Seleccionar]

..............
menmay(vector,promedio);
..................


Código (cpp) [Seleccionar]
void menmay (int vector[10], double promedio)
{
.............
int i,j=0,k=0;
.................


¡¡¡¡ Saluditos! ..... !!!!



eferion

Cita de: leosansan en 28 Abril 2014, 18:49 PM
Lo que no tiene ningún sentido es pasarle a la función "i" ya que no aporta ninguna información a la misma. Bastaría declarar int i en la función menmay y dejarla así:

Eso también lo comenté en el primer mensaje :)

leosansan

Cita de: eferion en 28 Abril 2014, 22:51 PM
Eso también lo comenté en el primer mensaje :)

Sorry, se me paso por alto.

¡¡¡¡ Saluditos! ..... !!!!



cacacolass

#8
Muchas gracias, me olvidé de ese ";" del último for y lo inicializar suma, ya lo había corregido, lo inicialicé a 0 porque sino puede tomar basura de la memoria.
Así quedó el código (apliqué todo lo sugerido):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void menmay (int vector[10], double promedio);
void free (void* ptr);

int main(int argc, char **argv)
{
int vector[10];
int i;
double suma=0.0, promedio=0.0;

srand(time(NULL));
for (i=0; i<10; i++)
{
vector[i] = rand() % 100;
printf("%3d", vector[i]);
suma += vector[i];
}

promedio = suma/10;
printf("\n Suma de los valores del vector: %.0lf", suma);
printf("\n Promedio de los valores del vector: %.0lf", promedio);
printf("\n");
menmay(vector,promedio);
return 0;
}

void menmay (int vector[10], double promedio)
{
int* menores;
int* mayores;
int i,j=0,k=0, cant=0, cant2=0;

menores = (int*)malloc (10*sizeof(int));
mayores = (int*)malloc (10*sizeof(int));


for (i=0; i<10; i++)
{
if (vector[i] < promedio)
{
menores[j] = vector[i];
cant++; j++;
}

else
{
mayores[k] = vector[i];
   cant2++; k++;
}

}
printf("Valores menores al promedio \n");
for (j=0;j<cant;j++)
printf("%3d",menores[j]);

free(menores);

printf("\nValores mayores al promedio \n");
for (k=0;k<cant2;k++)
printf("%3d",mayores[k]);

free(mayores);
}

void free (void* ptr);


P.D: Había pasado 'i' como parámetro para no volverlo a declarar de nuevo en la función. Pensé que no tenía nada de malo.

Muchas gracias por la ayuda, saludos !

eferion

Cita de: cacacolass en 30 Abril 2014, 05:12 AM
P.D: Había pasado 'i' como parámetro para no volverlo a declarar de nuevo en la función. Pensé que no tenía nada de malo.

Cuando tu pasas una variable como argumento de una función se realizan las siguientes acciones (por dar una idea):

* Se hace una copia de la variable.
* Se llama a la función.
* Se recupera la copia de la variable.

Cuando tu la declaras directamente como variable local:

* Se crea la variable ( bien en el stack, bien en los registros del procesador, depende de las optimizaciones del programa )

Pasar una variable como argumento es, como norma general, más costoso y confuso que declarar la variable como local.

Lo de confuso lo entenderás cuando te encuentres con una función ( yo lo he vivido ) con 78 argumentos.