¿se puede hacer el mismo efecto de anidar muchos bucles for con unos pocos?

Iniciado por MRx86, 10 Julio 2017, 20:27 PM

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

MRx86

Hola.. bueno mi duda es esa, si los bucles estan hechos para no tener que repetir la escritura de un codigo N veces, sino que tu le pasas a la definicion del bucle en el lenguaje de programacion que utilizas ese numero N para que de alguna forma repita e codigo ese numero de veces, entonces como hago lo siguiente:

voy a poner un ejemplo en C pero la duda (obviamente, pues la puse en programacion general) se refiere al hecho de hacer esto en cualquier lenguaje.

por ejemplo, si yo quiero hacer un programa que imprima en pantalla los numeros del 0 al 30, se haria normalmente asi:



#include <stdio.h>

int main ()
{
int i;

for (i = 0; i < 31; i++)
{
printf ("%d ", i);
}
}



pero si lo quisiera hacer controlando mediante un bucle for cada cifra, seria asi:



#include <stdio.h>

int main ()
{
int i[1]; /* i[0] va a contener la cifra de las decenas de cada numero contando del 0 al 30, i[1] va a contener las unidades */

for (i[0] = 0; i[0] < 3; i[0]++) /* aqui se itera sobre las decenas del intervalo cerrado [0, 30] */

/* en este for pongo el maximo a 3 para que iteren aqui las decenas del 0 al 29 (si lo pusiera a 4, se pasaria hasta el 39, logicamente): i[0]=0 i[1]=0,1,...,9, i[0]=1 i[1]=0,1,...,9,... */
{

for (i[1] = 0; i[1] < 10; i[1]++) /* aqui se itera sobre las unidades del mismo intervalo */
{
printf ("%d%d ", i[0], i[1]);
}
}
}



bueno ojala se entienda, si quieren pueden ejecutarlo ustedes para que vean, pero al punto:

Si quisiera mostrar los numeros del 0 al 100000000 tendria que escribir 8 bucles for anidados, por lo cual, pienso que se podria mediante un bucle for pivotar cada cifra mientras que, mediante otro bucle for, las aumenta en uno si la cifra anterior es mayor al maximo. Pero ahi esta el problema, esto no funciona por que el segundo bucle "pierde de vista" a las cifras anteriores a la que llego a ser mayor al maximo (o sea 10)...

Bueno de ninguna forma logre hacerlo asi "directamente", por lo cual lo que hice fue definir a cada cifra como un objeto (esto ya lo hice en C++ y no en C), y simplemente tenia que escribir un bucle for de la siguiente manera:

Código (cpp) [Seleccionar]


//NUMERO_DE_CIFRAS vale 8

Cifra *cifra = new Cifra [NUMERO_DE_CIFRAS];

Inicializar (cifra, NUMERO_DE_CIFRAS); // lo que hace esta funcion es enlazar cada elemento de cifra desde el primero (elemento 0) hasta el ultimo (elemento NUMERO_DE_CIFRAS)

//la clase Cifra tiene una metodo llamado "Incrementar" que toma como parametro un numero entero que se le suma a la cifra siguente (Cifra esta en una ligadura dinamica) si y solo si la cifra actual (la del objeto de la llamada a la funcion) es mayor a 10  

for (i = 0; i < NUMERO_DE_CIFRAS; i++)
{

//el objeto cifra tambien tiene como metodo una funcion llamada "Valor" que retorna el valor numerico de la cifra del objeto actual

printf ("%d ", cifra[i].Valor ());
cifra [i].Incrementar ();

}


pero como seguramente se habran dado cuenta se generan demasiadas llamadas a funciones para cada incremento de cada cifra, lo cual no es lo mejor...

Bueno ojala me hayan entendido lo que busco es saber si se puede comprimir el algoritmo para en vez de utilizar tantos bucles for para tantas cifras, solo algunos que puedan hacer lo mismo, igual que en vez de escribir un codigo del tipo



printf ("a");
printf ("b");
printf ("c");
printf ("d");
printf ("e");
printf ("f");
printf ("g");
printf ("h");
printf ("i");
...



se haga uno que escriba el caracter ascii de la "a" a la "z"

Saludos y gracias de antemano...
"Tengo una pregunta que a veces me tortura: ¿Estoy loco
yo, o los locos son los demas?"
- Albert Einstein

ivancea96

Cada algoritmo podrá ser comprimido de una forma u otra. por ejemplo, el ejemplo de las cifras, se podría comprimir en 1 bucle for deo 0 al 100000. Ese, es un método de compresión de <ese> algoritmo.

Para casos más genéricos, habría que hacer un algoritmo algo más complicado. Acabaríamos con un generador de variaciones con repetición.
Algo que necesitaremos es una forma de almacenar "por donde vamos para cada cifra". Lo que en los fors, son todas las variables de los fors. Ya que no tenemos N fors, ahora tendremos un array de tamaño N, cada uno con una cifra. Y sería simplemente hacer un bucle while, cuya condición será simplemente una bandera, llamémosla "acabar".
Dentro del while, incrementaremos en 1 la posición más a la derecha del vector (o la de la izquierda, depende de lo que se quiera conseguir).
- Si no ha desbordado (9 -> 0), no hacemos nada más. Simplemente, cogemos todas las cifras del vector, y las usamos para lo que queramos (printf en este caso).
- Si ha desbordado, incrementamos el siguiente en el vector (para esto, necesitaremos un while/for con un índice para saber por cuál vamos, que se reiniciará en cada vuelta del while externo). Y repetimos esto continuamente hasta que no desborde la cifra que aumentemos. En caso de que desborde la última cifra, significa que hemos acabado, y ponemos la bandera "acabar" a true (o hacemos un break, lo que sea, para salir del algoritmo, pues hemos acabado).

Con respecto a esto, puntualizar. La diferencia entre hacer esto y hacer los fors es casi "nula". En los fors tenemos variables, aquí tenemos el array. Aquí tenemos además el algoritmo y el índice para ir incrementando las cifras. En los fors tenemos un extra en código.

En cualquier caso, cada algoritmo a reducir debería ser analizado a parte. Si es posible, ir siempre a lo más legible sin perder eficiencia.

MRx86

Citar
Para casos más genéricos, habría que hacer un algoritmo algo más complicado. Acabaríamos con un generador de variaciones con repetición.
Algo que necesitaremos es una forma de almacenar "por donde vamos para cada cifra".

Ok ok eso me ayuda de mucho, investigare sobre que es un generador de variaciones con repeticion.

Citar
En cualquier caso, cada algoritmo a reducir debería ser analizado a parte. Si es posible, ir siempre a lo más legible sin perder eficiencia.

si, tienes razon, ciertamente, la eficiencia es fundamental, y mas en el proyecto que tengo en mente, el problema es ese algoritmo, pero investigare sobre lo anterior a ver si llego a algo.

Muchas gracias por tu ayuda!!
"Tengo una pregunta que a veces me tortura: ¿Estoy loco
yo, o los locos son los demas?"
- Albert Einstein

ivancea96

Lo de generador de variaciones con repetición, es, literalmente, un algoritmo que genera variaciones con repetición. Mira este link de combinatoria: http://www.vitutor.com/pro/1/a_3.html

MRx86

Citar

Mira este link de combinatoria: http://www.vitutor.com/pro/1/a_3.html


Ahhhhh okokok ya se que son... y si tiene mucho que ver con lo que queria saber, en esto es uno de los conceptos en los cuales se basan los sistemas de numeracion ¿verdad?

gracias por ayudarme
"Tengo una pregunta que a veces me tortura: ¿Estoy loco
yo, o los locos son los demas?"
- Albert Einstein

ivancea96

Cita de: MRx86 en 10 Julio 2017, 22:45 PM
Ahhhhh okokok ya se que son... y si tiene mucho que ver con lo que queria saber, en esto es uno de los conceptos en los cuales se basan los sistemas de numeracion ¿verdad?

Pues, podríamos decir que sí xD

MRx86

"Tengo una pregunta que a veces me tortura: ¿Estoy loco
yo, o los locos son los demas?"
- Albert Einstein