así que para añadir más gusto decidí ir más allá y generar el binomio de Newton de un exponente arbitario.
Obtener el desarrollo del binomio no genera ningún problema a partir del triángulo de Pascal. Además creo que tienes algún bug, si no mira las salidas de tu código para N=5, N=15 y N=25:
Citar
N=5
(a + b)^5 es:
5 4 3 2 2 3 4 5 a + 5a b + 10a b + 10a b + 5ab + b
Process returned 0 (0x0) execution time : 0.097 s Press any key to continue.
N=15
(a + b)^15 es:
15 14 13 2 12 3 11 4 10 5 9 6 8 7 7 8 6 9 5 10 4 11 3 12 2 13 14 15 a + 15a b + 105a b + 455a b + 1365a b + 3003a b + 5005a b + 6435a b + 6435a b + 5005a b + 3003a b + 1365a b + 455a b + 105a b + 15ab + b
Process returned 0 (0x0) execution time : 1.285 s Press any key to continue.
N=25
(a + b)^25 es:
25 24 23 2 22 3 21 4 20 5 19 6 18 7 17 8 16 9 15 10 14 11 13 12 12 13 11 14 10 15 9 16 8 17 7 18 6 19 5 20 4 21 3 22 2 23 24 25 a + 25a b + 300a b + 2300a b + 12650a b + 53130a b + 177100a b + 48 0700a b + 1081575a b + 2042975a b + 3268760a b + 4457400a b + 520030 0a b + 5200300a b + 4457400a b + 3268760a b + 2042975a b + 1081575 a b + 480700a b + 177100a b + 53130a b + 12650a b + 2300a b + 300a b + 25ab + b
Process returned 0 (0x0) execution time : 1.160 s Press any key to continue.
Por un lado no sé que son esos números que salen encima del binomio y faltan los exponentes de las potencias los del binomio..
Y ahora compara con las salidas del que código colgaré después:
Process returned 0 (0x0) execution time : 1.431 s Press any key to continue.
En la página web no sé si lo anterior sale exacto, pero para muestra una imagen de uno de los triángulos:
Y perdonen el signo más que sale al principio pero estoy perezoso, sólo había que considerar el caso del primer sumando a parte xD, algo tenemos que dejar para otras ocasiones.
7 6 5 2 4 3 3 4 2 5 6 7 a + 7a b + 21a b + 35a b + 35a b + 21a b + 7ab + b
Creo que habría que explicar, aunque sea brevemente, de donde salen esos número, no es plan de ponerse a multiplicar binomio tras binomio para comprobarlo.
Todo lo anterior se basa en la fórmula debida a Newton, como no, para el desarrollo de un binomio conocido por ello como binomio de Newton y que tiene esta expresión:
donde" esos" paréntesis son los llamados números combinatorios que se calculan, al menos en principio, a través de factoriales:
donde Vm,n son las llamadas variaciones de m elementos tomados n a n y Pn son las permutaciones de n elementos (consultar la Wikipedia para mayor información).
¿Y hay que calcular los factoriales necesariamente para hallar esos números combinatorios?. Pues si nos fijamos un poquitito vemos que podemos darles el esquinazo:
Observar que podemos evitar el cálculo de los factoriales sin más que multiplicar, en el caso del número combinatorio Cm,n, tantos factores en el numerador como indica n empezando por m y disminuyendo cada factor en una unidad, pero aún quedaría en el denominador el factorial de n.
¿Y no se podría evitar tanto cálculo para obtener los coeficientes del binomio de Newton?. Pues si, si nos fijamos en un pequeño detalle cuando los ordenamos en forma de triángulo:
¿No te dice nada?. No te preocupes ya que solamente hay que recordar un par de propiedades de los números combinatorios:
Si miras el triángulo anterior observarás que los números que aparecen en los extremos del triángulo son de este tipo, lo que implica que son iguales a uno.
Pero, ¿y los interiores?. También estamos de suerte ya que hay otra propiedad interesante:
Si la miras con atención viene a decir que cada elemento interior del triángulo es justito la suma de los dos que tiene encima, a su derecha y a su izquierda.
Con todo lo anterior se puede ya escribir el triángulo, y con ello calcular de forma simple, los coeficientes del binomio de Newton. Vuelve a fijarte en la figura que sigue y observa los dos hechos anteriores:
Si ya sé que tiene forma de pirámide,esos son cosas mías, tú fíjate en la mitad superior de la pirámide que es el triángulo de Pascal, es decir de coeficientes del ya tan nombrado binomio de Newton. Por cierto, ¿a qué está chula la pirámide?.
Y con lo explicado para los que no lo sabían o no recordaban ya están sin excusas para desarrollar códigos que generen el triángulo de Pascal. Puede hacerse con factoriales o sin ellos, usando arrays unidimensionales, bidimensionales o no usar arrays, con funciones o sin funciones, con recursividad o sin ella, en su elección estará la gracia y la mayor o menor eficiencia del código desarrollado, eso si procurando en lo posible que sea cortito y sin añadidos innecesarios, tampoco hay que sacar la artillería pesada para obtenerlo.¡¡¡Animensen señores y señoras!!!,
Y para que no se diga cuelgo un código que genera el dichosito triángulo y, por esta vez el binomio de Newton desarrollado pero que , insisto, no era el objetivo que yo planteaba ya que era desarrollar códigos que impriman sencillamente el triángulo. Una vez que lo obtienes el desarrollo del binomio es pan comido por lo que no lo veo interesante,
Y por cierto, este código no ha sido desarrollado para este fin sino para el tema de los rombos con asteriscos, pero ya que lo tenía a mano lo he adaptado para este fin por lo que no está muy optimizado .....ya vendrán otros más guays:
Código
#include <stdio.h>
int main(){
int i=0,j,l=0,m=0,k=1,n=15;
/*do{
printf("\nIntroduzca la potencia a calcular (mayor que cero): \n");
scanf("%d",&n);
}while ( n < 0 );*/
n=2*n+3;
char a[]="a^",b[]="b^";
int A[n][n];
for( i=0;i<n;i++)
for( j=0;j<n;j++)
A[i][j]=0;
A[0][n/2]=1;
i=1;
while(i<=n/2){
for( j=(n/2)-i;j<=i+(n/2);j++){
if(j==(n/2)-i || j==i+(n/2))
A[i][j]=1;
else
A[i][j]=A[i-1][j-1]+A[i-1][j+1];
}
i++;
}
for( i=0;i<n/2;i++){
printf("\t\n");
for( j=0;j<n;j++){
if(A[i][j]==0)
printf("%3c",' ');
elseif(A[i][j]!=0)
printf("%3d",A[i][j]);
}
}
printf("\n\n\t\t\t(a+b)^%d = \n",(n-3)/2);
i=1,k=0,l=1;
while(i<=n/2){
for( j=(n-3)/2-i;j<=i+(n-3)/2+2;j++){
if(A[i][j]!=0){
if(i==(n-3)/2){
if(j==(n-3)/2-i)
printf("%d %s%d %s%d",A[i][j],a,l-k,b,k);
else
printf(" + %d %s%d %s%d",A[i][j],a,l-k,b,k);
}
k++;
}
}
l++,k=0,i++;
}
putchar('\n');
return0;
}
Insisto en que es una adaptación rápida de lo hecho con otro objetivo pero no quería dejar pasar la ocasión de animar al personal.
¡¡¡¡ Saluditos! ..... !!!!
Y gracias a yoel_alejandro por iniciar el tema y su más que interesante aporte.
Y si, solo funcionaba por comandos. En el codeblocks se lo puedes meter en project -> "Set programs arguments".
Para que funcione tiene que ser un proyecto, no vale un archivo.
Soy un neófito total con la linea de comandos, sencillamente la odio y sólo por el hecho de ver correr este programa es por lo que me intereso en el tema. Es la vuelta a la edad de piedra xD.
¿Alguien podría explicarme brevemente el sistema de funcionamiento?. Gracias de antemano.
La salida que obtienes viene a corroborar el origen de mi duda:
Citar
Lo que queda en str1: da laZga
Copiado, nuevo str2: Entrada laZga
Y la cadena str2 impresa caracter a caracter: Entrada laZga Process returned 0 (0x0) execution time : 2.366 s Press any key to continue.
Lo que queda en str1 es justo lo que cabe "oficialmente" en str2 ..... otra vez, y van tres ejemplos. Fíjate que "da laZga" es justo la cadena str1 sin los 5 caracteres que "cabrían" en str2" de acuerdo a su dimensión. Curioso, ¿no?.
Aclaro mis sospechas:
* En str2 se copia la cadena str1, aunque str2 tenga declarada una dimensión inferior a str1. Eso sucede en los tres ejemplos aquí expuestos, hasta ahora.
* En str1 "queda" lo que "teóricamente" no cabia en str1 por tener menor dimensión.
Como ves tu ejemplo ha venido a ratificar mis sospechas en lugar de negarlo.
Y ¡ojo!, no digo que esto sea una regla general, que de acuerdo a las indicaciones del comportamiento de strcpy vulnera, pero...... los ejemplos parecen empeñarse en dar la razón a mis dudas ... por ahora.
Y repito, sólo es una sospecha de lo que puede ser un comportamiento general y no previsto.
Fijate en el contenido de str1: Ha dado overflow, te has salido del espacio de str2 y estás sobreescribiendo la cadena str1.
¿Por que en el otro ejemplo si funcionaba? Pues porque lo has interpretado mal: Se ha comido lo que está en negrita, lo que pasa es que no suena raro y lo has pasado por alto sin darte cuenta.
La salida tuya:
Citar
Cadena str1 antes del cambio: Cosita grande y hermosa
Cadena str2 antes del cambio: leosansan
Lo que queda en str1: nde y hermosa
Copiado, nuevo str2: Cosita grande y hermosa
Y la cadena str2 impresa caracter a caracter: Cosita grande y hermosa
longitud de la nueva cadena str2= 23
Process returned 0 (0x0) execution time : 0.102
Por ejemplo esta otra salida:
Citar
Cadena str1 antes del cambio: Cosita grande y hermosa
Cadena str2 antes del cambio: leosansan
Lo que queda en str1: nde y hermosa
Copiado, nuevo str2: Cosita grande y hermosa
Y la cadena str2 impresa caracter a caracter: Cosita grande y hermosa
Cadena str0 despues del cambio:
Gran Canaria es Cosita grande y hermosa
Cadena str3 despues del cambio:
leosansan es de Gran Canaria
Process returned 0 (0x0) execution time : 1.165 s Press any key to continue.
A este código:
Código
#include <stdio.h>
#include <string.h>
int main ()
{
int i;
char str0[]="Gran Canaria es Cosita grande y hermosa";
char str1[]="Cosita grande y hermosa";
char str2[]="leosansan";
char str3[]="leosansan es de Gran Canaria";
printf("\nCadena str1 antes del cambio:\n%s",str1);
printf("\n\nCadena str2 antes del cambio:\n%s",str2);
strcpy(str2,str1);
printf("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
for( i=0; str2[i]; i++)
printf("%c",str2[i]);
printf("\n\nCadena str0 despues del cambio:\n\n%s",str0);
printf("\n\nCadena str3 despues del cambio:\n\n%s\n\n",str3);
return0;
}
Lo realmente raro es que si declaro varias cadenas str, tres o cuatro, además de str1 y str2, lo que queda en str1 siempre es el resto de lo que teóricamente "sobra en str2, en tu ejemplo y en el mio. Será casualidad o no, pero es un resultado cuando menos inesperado. ¿Por qué juntamente queda en str1 y no en las otras cadenas que he declarado?. He ahí mi gran duda, ¿será casualidad o es un comportamiento normal de la función strcpy "dejar" el resto de la cadena que no quepa en str2?. Y a los ejemplos me remito, claro que tan sólo son dos ejemplos y ya sabemos que no se puede pasr del particular al general, pero ......
Pero lo que dice el manual está claro, yo sólo pongo de manifiesto un hecho contrastado en esos dos ejemplos.
Copy string Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.
Sin embargo ..... supongo que es el propio compilador el que lleva a cabo la operación de ampliar el espacio de la cadena receptora, que en principio es de 10 y podría provocar el overflow, pero en la práctica eso no sucede.
Está es la salida al código de ejemplo:
Citar
Cadena str1 antes del cambio: A ver si cabe la cadena str1 en srt2
Cadena str2 antes del cambio: leosansan
Lo que queda en str1: abe la cadena str1 en srt2
Copiado, nuevo str2: A ver si cabe la cadena str1 en srt2
Y la cadena str2 impresa caracter a caracter: A ver si cabe la cadena str1 en srt2
longitud de la nueva cadena str2= 36 Process returned 0 (0x0) execution time : 1.500 s Press any key to continue.
Como pueden observar, str2 "se metió" en la cadena str1 que originalmente erra de dimensión 10 sin problemas.
Eso si, destacar que si str2 no tiene suficiente dimensión quedará en la cadena original el "resto" de la dicha cadena:
Código
#include <stdio.h>
#include <string.h>
int main ()
{
int i;
char str1[]="A ver si cabe la cadena str1 en srt2";
char str2[10]="leosansan";
printf("\nCadena str1 antes del cambio:\n%s",str1);
printf("\n\nCadena str2 antes del cambio:\n%s",str2);
strcpy(str2,str1);
printf("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
for( i=0;str2[i]; i++)
printf("%c",str2[i]);
printf("\n\nlongitud de la nueva cadena str2=\n%d", strlen(str2));
return0;
}
Espero no haberme liado con este rollito, ¿o tal vez si?. Ya me contaran ustedes.
Pero apenas en C++, ya te digo que no sé muy bien como imprimir de forma avanzada. No obstante continuo con mis aportaciones, para que vean lo que puede dar de sí este tema:
................................................... ¿Más fácil? De eso nada xD
Para empezar rompe el enfoque arriba-abajo, además para sacarla tendrías que hacer unas series de fourier muy divertidas... Y probablemente alguna casilla te salga mal ya que no es exacta y las casillas no admiten decimales.
¡No hombre!, no pensaba en ese sistema, para eso ya tengo el Mathematica y el Matlab.
Pensaba en esta idea:
Citar
f(x)=a/2 ...... 0<=x<=a/2
f(x)=-a/2 ...... -a/2<x<a
Para ello me apoyo en el uso del gotoxy, bien mediante la librería de conio, más exactamente la conio2.h:
Esta vez, en vista de que "no cabe" en la página todas las funciones que genero, de 3 a 19 o 20, las metí en un vídeo, ..... tranquilos, dura menos de un minutito: