Ayuda: C# >>> Nested-For Loop

B

Hola a tod@s,

Estoy aprendiendo a programar por mi cuenta y he elegido C# como lenguaje de entrada para así luego moverme si necesito a otro tipo de lenguaje de programación.

Estoy siguiendo varios tutoriales y no termino de entender los nested-for loops. Comprendo su sintaxis y los sé ejecutar pero no entiendo cómo funcionan, cómo generan el output. Necesitaría algo de ayuda.

Básicamente he sabido llegar por mi cuenta a tod@s los ejercicios propuestos de Nested-For loop salvo este? Alguien podría ayudarme? No quiero el resultado (quiero aprender) sino la lógica que hay en los for anidados:

Qu 2. Using for loop print the following output on console.
1
121
12321
1234321
123454321

Mil gracias por adelantado, de verdad.

Atuit

supongo que sería algo así,

for(int i=1;i<6;i++){
        print(i);
        for(int j = (i-1);j>0;j--){
          print(j);
       }
       print(\n);
}
1 2 respuestas
B

#2 Eso da como resultado:
1
2
3
4
5

Por qué?

2 respuestas
HeXaN

#3 Coge papel, bolígrafo y realiza los bucles a mano para que comprendas qué hacen.

1 respuesta
B

#4 Muchas gracias, lo he intentado, pero no entiendo la lógica. Antes de que saltemos, me explico: Entiendo la lógica del primer for (es decir, para el intervalo en el que 1 < i < 5 me iteras i++ hasta el 5), pero a partir de ahí no entiendo el proceso. Sé que tiene que dar 5 líneas porque hace 5 iteraciones que cumple las dos condiciones o me hago la picha un lío?

1 respuesta
Atuit

#3 usa el print sin salto de linea, ahora mismo no me acuerdo como era, en c hay print y println ( sería el primero)

edit:
buscando un poco , sería console.write(string) en vez de console.writeline(string)

edit2 : #5
la primera iteración, como tu bien dices ( la del i de 1 a 5) es para iterar ascendentemente, pero luego hay que volver a bajar a 1, de ahí la segunda iteracion j, que va desde 1 posicion antes de la i, hasta el 0 , siempre y cuando la j sea mayor que o ( esto hace que no baje de 1). todo esto lo vas imprimiendo en la misma linea, una vez acabes la iteración de la j, quieres imprimir un salto de línea.

edit 3 : fui un caliente xD , lo que yo hago es
1 2 3 4 5 4 3 2 1
2 3 4 5 4 3 2 1
3 4 5 4 3 2 1
...
ahora edito con el código

B

#2 Eso da
1
21
321
4321
54321

EDIT: Ya he visto la lógica que usas en #6. Gracias lo miraré
Lo he puesto como dijiste.. qué lógica usaste? Eso es lo que quiero, porque no sé proponer la premisa para "j"

class Program
    {
        static void Main(string[] args)
        {
            int i;
            int j;

        for (i = 1; i <6; i++)
        {
            Console.Write(i);
            for (j = (i -1); j > 0; j--)
            {
                Console.Write(j);
            }
        
        Console.Write("\n");
        }

        Console.ReadLine();        

    }
}
1 respuesta
Atuit

#7

using System;
					
public class Program
{
	public static void Main()
	{
		for(int i = 1; i<6; i++){
			for(int j = 1;j<=i;j++){
				Console.Write(j +" ");
			}
			for(int j = (i-1);j>0;j--){
			
			Console.Write(j +" ");
		}
		Console.WriteLine();
	}
}
}

el resultado según el joodle sería :
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
1 2 3 4 5 4 3 2 1

https://dotnetfiddle.net/Yq41bm

2 respuestas
Geekalvaro

#8 La gracia está en hacerlo solo con dos for. Estoy casi seguro que es posible.

2 respuestas
Atuit

#9 si , es posible, pero con ello lo que se me ocurre a bote pronto es ir guardando la salida en dos string , uno para el aumento, y el otro para la disminución. y luego unirlos.

B

#8 A ver si lo entiendo.. yo intento descomponer y dejo las tripas de mis sesos abiertas para que las buitréeis.

  • Nunca imprimimos i, por lo tanto su función es sólo iterativa (sumar para dar más casos a la variable "j")
  • Son tres anidados. Yo creía por todo lo visto que serían sólo dos. Pero tiene lógica porque hay que subir y bajar del 1 al 5 y del 5 al 1.
  • La primera iteración (la de la i) te va a decir que el resultado tendrá 5 iteraciones (5 líneas, para entendernos) crecientes del 1 al 5.
  • Y hasta aquí mi lógica con el for anidado.. con lo bien que entendí el ejercicio de las coordenadas posibles (
    )

EDIT: Voy a coger papel y boli como dice Hexan, a ver si con el resultado lo entiendo

1 respuesta
Atuit

#11

ahora edito con la explicación que dí atrás.

esto sería con dos for según dijo #9

using System;
					
public class Program
{
	public static void Main()
	{
		string aumento = "";
		string disminuyo = "";
		for(int i = 1; i<6; i++){
			aumento += i + " ";
			disminuyo = "";
			for(int j = (i-1) ;j>0;j--){
				disminuyo += j+ " ";
			}
			
		Console.WriteLine(aumento+disminuyo);
	}
}
}

https://dotnetfiddle.net/A3HRel

el truco realmente está en pensar en que como bien dices :
1) el primer for , para iterar cuantas veces quieres repetir la operación
2) dentro hay 2 acciones unidas:
2.1) la primera sería aumentar de 1 en 1 , desde el 1 hasta el el tamaño de esa ronda ( es decir, i)
2.2)la segunda sería disminuir, desde 1 antes de i, hasta 1

en #8 lo hice con 3 for para distinguir esas dos acciones, que aquí deje en uno solo.

y si , yo aprendí a programar en papel, es lo mejor que puedes hacer para comprender por los estados de tu bucle, de la misma manera que en cualquier IDE puedes debuguear para una mayor rapidez.

1 1 respuesta
B

#12 Llevo un rato y no lo veo..
Quiero decir entiendo el incremento de líneas gracias a la iteración de la "i" (que da las cinco líneas)
Una vez dentro de cada línea no entiendo cómo hacemos para crecer o decrecer y mostrarlo en pantalla.. es decir no entiendo la lógica de la "j"+
Sería algo así como "para cada iteración "i" muéstrame las posibles iteraciones "j" que crezcan hasta el 5 y luego las posibles iteraciones "j" para que vuelvan a decrecer a 1. Ah si tiene lógica tus tres for anidados.
Seguiré investigando..
Alguna página o libro que ayude con lo de "programar en papel"?

1 respuesta
Atuit

#13 no tengo ningún titulo a mano para programar a mano, te diría que hicieras sobre todo hincapie en los algoritmos , o en los psuedocodigo.

Y a ver si consigo ayudarte algo.

lo que queremos es una sucesión de numeros.
si quisieramos imprimir por ejemplo:
1
2
3
4
5.
El algoritmo sería algo así ( Ojo , ten en cuenta que en programación, nada tiene una sola solución, solo te proporcionaré una o dos posible/s)
Opción 1)

empieza programa
imprimo 1
imprimo 2
imprimo 3
imprimo 4
imprimo 5
fin programa

opción 2)

Empieza programa
Bucle:
          Inicializo varible numérica a 1,
         Mientras  variable menor que 6:
                        Imprimo variable
                        Sumo 1 a la variable 
Fin Bucle
Fin  Programa

Ahora, si quisieramos algo tal que asi:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
Algoritmo

Inicio programa
Bucle:
          Inicializo varible numérica a 1, // Aquí iteramos el número de veces que corre el bucle
         Mientras  variable menor que 6:
                        Bucle2:
                                     Inicializa variable2 numérica a 1 // valor inicial que siempre empieza la impresión
                                     Mientras variable2 Menor o igual que variable:
                                                 Imprimo variable2
                                                Sumo 1 a la variable2
                                    Fin Bucle2
                                    Sumo 1 a la variable 
                                   Imprimo salto de línea
Fin Bucle
Fin  Programa

Ahora, que pasa si queremos lo que tu proponías
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
1 2 3 4 5 4 3 2 1

Opción 1 -> mi opción de los 3 bucles ( 1 for anidando a 2)
¿porqúe?. Separé el problema en 2 partes , la primera vendría siendo el algoritmo anterior, pero nos faltaría la parte "espejo" que vendría a ser el segundo bucle. el cual iría comprendido entre <fin bucle 2> y <sumo 1 a la variable>

Opción 2-> la que describí en #12 (1 for anidado en otro)
¿porqué?. Volví a separar el problema en dos. pero esta vez, solucioné la primera parte de otra manera

Inicio programa
Iniciaizo variable de tipo char[]  a por defecto // lo que viene siendo string ""
Bucle:
          Inicializo varible numérica a 1, // Aquí iteramos el número de veces que corre el bucle
         Mientras  variable menor que 6:
                        le sumo a variable char[] el valor de i
                        Imprimo variable char[]
                        Sumo 1 a la variable 
                        Imprimo salto de línea
Fin Bucle
Fin  Programa

Hasta aquí tendríamos
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
Por ende, nos faltaría la parte "espejo", el cual se soluciona con otro bucle anidado

Inicio programa
Inicializo variable de tipo char[]  a por defecto // lo que viene siendo string ""
Bucle:
          Inicializo varible numérica a 1, // Aquí iteramos el número de veces que corre el bucle
         Mientras  variable menor que 6:
                        le sumo a variable char[] el valor de i
                        Imprimo variable char[]
                        //lo nuevo
                        Bucle2:
                                   Inicializo variable2 numérica a el valor de variable menos 1 // ya que no queremos que este se repita
                                   //Hasta cuando? el valor sea 1, o mayor que 0
                                  Mientras variable2 Mayor o igual que 1
                                   Imprimo variable2
                                   Resto 1 a variable2
                        Fin Bucle2
                            //FIN NUEVO
                        Sumo 1 a la variable 
                        Imprimo salto de línea
Fin Bucle
Fin  Programa

Espero haberme explicado bien.

1 respuesta
B

#14 Después de un par de horas por fin he entendido cómo funciona. Y para ello voy a dejar la madre de todas las ayudas: EL PUTO DEBUG
Como no lo entendía encontré la solución por internet. No porque me interesara especialmente ya que quiero aprender, sino para analizarla. No entendía ni papa.
Quiero decir, veía la idea general pero cuando entraba en los for anidados me moría. De hecho no sabía que mi error principal era creer que i anidaba a j y j anidaba a k, cuando en realidad i anidaba a j y a k a la vez.

Lo guapo ha sido mirando algún tutorial hasta conocer el debug. He hecho la secuencia desde el inicio como 5 veces y por fin lo he entendido. Basicamente explora todas las posibilidades con las premisas dadas. No sé si sería capaz de emularlo pensando desde 0, es decir, hallar la solución, pero desde luego que comprendo ahora como funciona. Si ya aprendo a formularlo, miel sobre hojuelas xD

En realidad es muy sencillo de entender una vez que ves como funciona paso a paso en el debug. Ahora, abstaer la mente para formularlo sí que es el reto.

A todos los que me han ayudado, mil gracias por vuestros consejos y si algunos sabéis de alguna página o libro para aprender a pensar en algoritmos o loops lo agradecería. Sé que parece echarle morro, pero nada más lejos de la realidad. Mi objetivo es aprender a programar y no pararé hasta conseguirlo.

Un saludo,

PD: Dejo la solución para los curiosos:

class Program
    {
        static void Main(string[] args)
        {
            int numberoflayer;
            int number;
            int i;

        Console.WriteLine("Please enter the layers you want");
        numberoflayer = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("Print paramid");

        // Total number of layer for pramid 
        for (i = 1; i <= numberoflayer; i++)  
        {
            //increase the value  
            for (number = 1; number <= i; number++) 
                Console.Write(number);
            
            //decrease the value
            for (number = (i - 1); number >= 1; number--)  
                Console.Write(number);
                Console.WriteLine();
            

        }

        Console.ReadLine();
    }
           
}

Spoiler:

B

Te sirve esto #1 ?

int main() {
  for(int i = 0; i < 5; ++i) {
    for(int j = 0; j <= 2 * i; ++j) {
      int val = j < i ? j : 2 * i - j;
      cout << val + 1;
    }
    cout << endl;
  }
}

Basicamente, tienes que printar 5 lineas y por eso el for de arriba da 5 vueltas.
En la iesima linea (empezando por cero) es facil ver que printamos 2 * i + 1 numeros: i ascendentes, el "pico" e i descendentes.
Sabiendo esto, podemos dar las i primeras vueltas sin preocuparnos por el valor del numero demasiado. Las i - 1 ultimas iteraciones son descendentes empezando por i + 1, y de ahi el 2 * i - j

1
JuAn4k4

Nested loop explained: Cuenta de 1 a 10. Repetir 3 veces.

Tu problema:

Contar de 1 a i-1 y luego de i a 1. Repetir i veces.

Primero entender, despues escribir código.

1

Usuarios habituales