Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: flacc en 14 Mayo 2010, 22:38 pm



Título: Les presento mi calculadora de ncr!!!(ahora si que si!!!)
Publicado por: flacc en 14 Mayo 2010, 22:38 pm
hola, se preguntarán alguno que diablos es ncr, bueno mas especificamente es una parte del Teorema del binomio (http://es.wikipedia.org/wiki/Teorema_del_binomio).

Mas especificamente es:

(http://r.i.elhacker.net/cache?url=http://upload.wikimedia.org/math/c/2/d/c2d02458d8c35f11e465c639ba62f081.png)

Entonces como en mis ratos libres y de oseo aprendo C, y dado que no tengo para comprarme una calculadora de esas Casio y que solo tengo una de esas chinas o japonesas, en fin, me hice mi propia calculadora para eso que entrega detalladamente los resultados para comprobarlos(si quieren a mano)...

Quiero agradecer al usuario dr.~ que se dio el trabajo de ayudarme con una duda... en  fin... y al foro.elhacker.net (que es genial ;-))
esta echa en c con el compilador dev c/c++, como dije antes no me resulta el [ code=c][/code ] asi que lo pongo de forma normal, si algun moderador lo puede arreglar se lo agradecería...
espero que a alguien le sirva tanto como a mi, saludos, gracias por la ayuda y si ven que le falta algo o quieren  aportar algo diganmelo y lo agrego.. (tengan en cuenta que tengo 17 y estoy aprendiendo asi que pongan el codigo para agregarlo)...

Código
  1. /* NCR Calculator v. 1.0.6 <versión estandar>*/
  2. /* foro.elchacker.net */
  3. #include <stdio.h>
  4.  
  5. int
  6. main( void )
  7. {
  8. signed long n, k, nf, kf, resta, restaf, x, y;
  9. char opcion;
  10. int ch;
  11.  
  12. do
  13. {
  14. printf( "\nIngrese n y k: " );
  15. fflush( stdout);
  16. scanf( "%ld %ld", &n, &k );
  17. while ( (ch = fgetc( stdin )) != EOF && ch != '\n' );
  18.  
  19. nf = 1;
  20. kf = 1;
  21. resta = n - k;
  22. restaf = 1;
  23.  
  24. while ( n > 1 ) /* factorial de n */
  25. {
  26. nf *= n--;
  27. }
  28.  
  29. while ( k > 1 ) /* factorial de k */
  30. {
  31. kf *= k--;
  32. }
  33.  
  34. while ( resta > 1 ) /* factorial de (n - k) */
  35. {
  36. restaf *= resta--;
  37. }
  38.  
  39. x = kf * restaf; /* k! * (n - k)! */
  40. y = nf / x; /* n! / (k! * (n - k)!) */
  41.  
  42. /* resultados */
  43. printf( "\nn! = %ld\n"
  44. "k! = %ld\n"
  45. "(n - k)! = %ld\n"
  46. "k! * (n - k)! = %ld\n"
  47. "n! / [k! (n - k)!] = %ld\n"
  48. "--------------------------\n"
  49. "Resultado final (ncr): %ld\n", nf, kf, restaf, x, y, y );
  50.  
  51. printf( "\nContinuar? S/n: " );
  52. fflush( stdout );
  53. scanf( "%c", &opcion );
  54. while ( (ch = fgetc( stdin )) != EOF && ch != '\n' );
  55. }
  56. while ( opcion == 's' || opcion == 'S' );
  57.  
  58. return 0;
  59. }
  60.  
  61.  

ya.. y aunque no entendi mucho acerca de limpiar el buffer y eso de la consola..
ya esta estandarizada gracias a nicolas_cof...
de todas fomas conservo la version antigua por seacaso... hasta le hice un icono.. pero en fin... todavia no he legado a esa parte del buffer... solo se pocas cosas.... y sigo quebrandome la cabesa con eso de los signos logicos y la tabla de verdad de los operdadores logicos que aparece en el libro introduccion a la programacion en c...

haci que ya esta... saludoss y gracias por tomarse la molestia de entrar  a ver mi post...


Título: Re: Les presento mi calculadora de ncr!!!
Publicado por: @synthesize en 14 Mayo 2010, 23:15 pm
[ code=c]  [/code ]


Título: Re: Les presento mi calculadora de ncr!!!
Publicado por: flacc en 15 Mayo 2010, 02:44 am
gracias... no tenia idea...


Título: Re: Les presento mi calculadora de ncr!!!
Publicado por: Gallu en 15 Mayo 2010, 13:27 pm
Si le quitas las llamadas a System tu aplicación será multiplataforma  ;D


Título: Re: Les presento mi calculadora de ncr!!!
Publicado por: Horricreu en 15 Mayo 2010, 13:34 pm
Si le quitas las llamadas a System tu aplicación será multiplataforma  ;D

+1. Estás haciendo:

Código
  1. system("pause>nul");


Esto no es standard, puedes utilizar getchar() (http://www.cplusplus.com/reference/clibrary/cstdio/getchar/) de la librería stdio, que la estás utilizando en tu código.

Saludos  :P


Título: Re: Les presento mi calculadora de ncr!!!
Publicado por: Og. en 15 Mayo 2010, 16:42 pm
Deberías de tener la variable y en punto flotante y hacer:
Código
  1. y = (float)nf/(float)x

Así tendrás mas presicion en tu solución.

Saludos.


Título: Re: Les presento mi calculadora de ncr!!!
Publicado por: flacc en 16 Mayo 2010, 03:54 am
gracias por los consejos, y eso de los puntos flotantes no lo entendi mucho pero lo probaré..
ojala me pudieran explicar..
saludos y gracias..


Título: Re: Les presento mi calculadora de ncr!!!
Publicado por: Gallu en 17 Mayo 2010, 17:34 pm
Lo que te dice Og. es que la variable que guarda el resultado la declares como float , te mostrara los decimales y será mas presiso ...


Título: Re: Les presento mi calculadora de ncr!!!
Publicado por: flacc en 17 Mayo 2010, 21:38 pm
gracias... voy a modificar el post con las mejoras que me han dicho...
hasta el momento tengo lo de float pero lo del getchar lo estoy investigando...
cuando lo tenga listo modifico el post..
saludoss y gracias


Título: Re: Les presento mi calculadora de ncr!!!(modificado con el nuevo codigo!!!)
Publicado por: Horricreu en 18 Mayo 2010, 18:26 pm
Continua sin ser standard...  >:D

Te dije, que podías utilizar getchar() (http://www.cplusplus.com/reference/clibrary/cstdio/getchar/) de la librería stdio y, así no hace falta que uses la maldita conio con su getche() :¬¬

Venga, que te falta un pequeño paso para ser multiplataforma...

Saludos :P

EDITO: también puedes quitar gotoxy() (también de conio) y usar tabuladores y saltos de línea... ahora sí, a por la multiplataforma :laugh:


Título: Re: Les presento mi calculadora de ncr!!!(modificado con el nuevo codigo!!!)
Publicado por: flacc en 18 Mayo 2010, 23:13 pm
ok, ok pero para que ese tono...
yo solo quería hacerla un poco mejor...y pense que getch() era lo mismo que getchar(),
ademas no tenía idea de que era parte de conio2.h, yo solo la puse para usar gotoxy(), ademas eso lo saque de un ejemplo en la red, por que no me daba pausa con getchar(), o no la se usar..
en fin... seguiré trabajando haber si queda mejor...
saludoss


Título: Re: Les presento mi calculadora de ncr!!!(modificado con el nuevo codigo!!!)
Publicado por: leogtz en 19 Mayo 2010, 03:49 am
Si el getchar() no hace su trabajo quiere decir que el buffer no está limpio.


Título: Re: Les presento mi calculadora de ncr!!!(modificado con el nuevo codigo!!!)
Publicado por: flacc en 19 Mayo 2010, 13:32 pm
Citar
Si el getchar() no hace su trabajo quiere decir que el buffer no está limpio.

entonces como limpio el buffer...


Título: Re: Les presento mi calculadora de ncr!!!(modificado con el nuevo codigo!!!)
Publicado por: h0oke en 19 Mayo 2010, 13:41 pm
Puedes utilizar:

Código
  1. fflush(stdin); // Limpia el buffer de entrada

EDIT: Si utilizas los pauses a través de system("Pause"), getchar(), etc, únicamente para ver los resultados, es preferible que para ahorrarte ese tipo de cosas, ejecutes tu programa a través de una consola.


Título: Re: Les presento mi calculadora de ncr!!!(modificado con el nuevo codigo!!!)
Publicado por: Gallu en 19 Mayo 2010, 15:24 pm
Puedes utilizar:

Código
  1. fflush(stdin); // Limpia el buffer de entrada

EDIT: Si utilizas los pauses a través de system("Pause"), getchar(), etc, únicamente para ver los resultados, es preferible que para ahorrarte ese tipo de cosas, ejecutes tu programa a través de una consola.

Se ha comentado ya acerca del uso del fflush(stdin), mirate lo siguiente

http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html

para limpiar el buffer de entrada es mejor usar
Código
  1. while(getchar() !='\n');
  2.  


Título: Re: Les presento mi calculadora de ncr!!!(modificado con el nuevo codigo!!!)
Publicado por: nicolas_cof en 19 Mayo 2010, 17:51 pm
Antes que nada mini_nauta felicitaciones por emprenderte a codear!

Aca te dejo tu codigo con algunas mejoras y mas portable, cualquier duda pegue el grito nomas ;D

Código:
#include <stdio.h>

int
main( void )
{
signed long n, k, nf, kf, resta, restaf, x, y;
char opcion;
int ch;

do
{
printf( "\nIngrese n y k: " );
fflush( stdout);
scanf( "%ld %ld", &n, &k );
while ( (ch = fgetc( stdin )) != EOF && ch != '\n' );

nf = 1;
kf = 1;
resta = n - k;
restaf = 1;

while ( n > 1 ) /* factorial de n */
{
nf *= n--;
}

while ( k > 1 ) /* factorial de k */
{
kf *= k--;
}

while ( resta > 1 ) /* factorial de (n - k) */
{
restaf *= resta--;
}

x = kf * restaf; /* k! * (n - k)! */
y = nf / x; /* n! / (k! * (n - k)!) */

/* resultados */
printf( "\nn! = %ld\n"
"k! = %ld\n"
"(n - k)! = %ld\n"
"k! * (n - k)! = %ld\n"
"n! / [k! (n - k)!] = %ld\n"
"--------------------------\n"
"Resultado final (ncr): %ld\n", nf, kf, restaf, x, y, y );

printf( "\nContinuar? S/n: " );
fflush( stdout );
scanf( "%c", &opcion );
while ( (ch = fgetc( stdin )) != EOF && ch != '\n' );
}
while ( opcion == 's' || opcion == 'S' );

return 0;
}

Salu10.


Título: Re: Les presento mi calculadora de ncr!!!(modificado con el nuevo codigo!!!)
Publicado por: Horricreu en 19 Mayo 2010, 17:52 pm
¡Exacto! A esto me refería... a ver si puedo ver el código multiplataforma :silbar:

Saludos :P

PD: perdona si te ha parecido un tono agresivo, sólo quería ayudarte a "mejorar" :)

Advertencia - mientras estabas escribiendo, una nueva respuesta fue publicada. Probablemente desees revisar tu mensaje


Título: Re: Les presento mi calculadora de ncr!!!(modificado con el nuevo codigo!!!)
Publicado por: flacc en 21 Mayo 2010, 04:18 am
gracias... justamente buscaba poner esa opción de si continuar o no... ;-)....


Título: Re: Les presento mi calculadora de ncr!!!(ahora si que si!!!)
Publicado por: leosansan en 8 Mayo 2013, 14:39 pm
[Recopilatorio] Sources interesantes

hola, se preguntarán alguno que diablos es ncr, bueno mas especificamente es una parte del Teorema del binomio (http://es.wikipedia.org/wiki/Teorema_del_binomio).

Mas especificamente es:

(http://r.i.elhacker.net/cache?url=http://upload.wikimedia.org/math/c/2/d/c2d02458d8c35f11e465c639ba62f081.png)

Entonces como en mis ratos libres y de oseo aprendo C, y dado que no tengo para comprarme una calculadora de esas Casio y que solo tengo una de esas chinas o japonesas, en fin, me hice mi propia calculadora para eso que entrega detalladamente los resultados para comprobarlos(si quieren a mano)...

..................................................

El uso de los factoriales para el cálculo de los números combinatorios tiene el inconveniente de su tamaño, desbordan las posibilidades de C/C++ desde 14 o 15. Una muestra de la salida de tu código:

Código
  1.  
  2. Ingrese n y k: 16
  3. 14
  4.  
  5. n! = 2004189184
  6. k! = 1278945280
  7. (n - k)! = 2
  8. k! * (n - k)! = -1737076736
  9. n! / [k! (n - k)!] = -1
  10. --------------------------
  11. Resultado final (ncr): -1
  12.  

Decepcionante, ¿verdad?.

Para evitarlo existe otra forma de calcular los números combinatorios que técnicamente consiste en dividir las variaciones de n tomados de p en p entre las permutaciones de p. Vamos que con un ejemplo se ve que es más fácil de lo que parece:

Combinaciones(15,4)= 15/4 * 14/3 * 13/2 * 12/1.

Y aún así se puede mejorar la eficiencia del cálculo. Por ejemplo:

Combinaciones(15,12)=15/12*14/11*13/10*12/9*11/8*10/7*.....

Muy largo, ¿verdad?. Pero eso se puede remediar aprovechado una propiedad de los números combinatorios que establece que :

Combinaciones(n,p)=Combinaciones(n,n-p)

Y aplicada al caso último daría:

Combinaciones(15,12)=Combinaciones(15,3)=15/3 *14/2 *13/1

Mucho más breve que el anterior método.

Así, aprovechando estas dos propiedades, la primera para cuando es inferior a la mitad de n y la segunda para cuando es superior surge el código mágico que te permitirá "meter" de exponente 20 y más sin problemas de que el C/C++ "cruja" soltando números "raros" porque se salen de sus capacidades:


Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int comb(int n,int p)
  5. {
  6.    int i;
  7.    if (n < 0 || p < 0 || p > n) return 0;
  8.    float c = 1;
  9.    if (p>n/2)
  10.        p=n-p;
  11.    for ( p; p>=1; p--,n--)
  12.        c*= (float)n/p;
  13.    return (int)c;
  14. }
  15. int main()
  16. {
  17.    int n, p, num , y;
  18.    while (1){
  19.        printf("\n\nIngrese n (0 para SALIR): " );
  20.    if (n==0)
  21.        break;
  22.    fflush( stdout);
  23.    scanf(" %d", &n);
  24.    printf("\nIngrese p : " );
  25.    fflush( stdout);
  26.    scanf(" %d", &p);
  27.    printf("\ncombinaciones(%d,%d)= %d",n,p,comb(n,p));
  28.    fflush( stdout);
  29.    }
  30.    return 0;
  31. }
  32.  

Y ahora puedo meter números más grandes:

Código
  1. Ingrese n (0 para SALIR): 40
  2.  
  3. Ingrese p : 35
  4.  
  5. combinaciones(40,35)= 658008
  6.  
  7. Ingrese n (0 para SALIR): 35
  8.  
  9. Ingrese p : 12
  10.  
  11. combinaciones(35,12)= 834451776
  12.  

Saluditos!. ...  (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)

P.D: Más en http://foro.elhacker.net/programacion_cc/teorema_binomial-t388312.0.html