Creazione di un triangolo con i cicli for in Java

1. Introduzione

In questo tutorial, esploreremo diversi modi per stampare un triangolo in Java.

Esistono, naturalmente, molti tipi di triangoli. Qui ne esploreremo solo un paio: triangoli destro e isoscele.

2. Costruire un triangolo rettangolo

Il triangolo rettangolo è il tipo più semplice di triangolo che studieremo. Diamo una rapida occhiata all'output che vogliamo ottenere:

* ** *** **** *****

Qui, notiamo che il triangolo è composto da 5 righe, ciascuna con un numero di stelle uguale al numero di riga corrente. Naturalmente, questa osservazione può essere generalizzata: per ogni riga da 1 a N , dobbiamo stampare r stelle, dove r è la riga corrente e N è il numero totale di righe.

Quindi, costruiamo il triangolo usando due cicli for :

public static String printARightTriangle(int N) { StringBuilder result = new StringBuilder(); for (int r = 1; r <= N; r++) { for (int j = 1; j <= r; j++) { result.append("*"); } result.append(System.lineSeparator()); } return result.toString(); }

3. Costruire un triangolo isoscele

Ora, diamo un'occhiata alla forma di un triangolo isoscele:

 * *** ***** ******* *********

Cosa vediamo in questo caso? Notiamo che, oltre alle stelle, dobbiamo anche stampare degli spazi per ogni riga. Quindi, dobbiamo capire quanti spazi e stelle dobbiamo stampare per ogni riga. Naturalmente, il numero di spazi e stelle dipende dalla riga corrente.

Innanzitutto, vediamo che dobbiamo stampare 4 spazi per la prima riga e, mentre scendiamo lungo il triangolo, abbiamo bisogno di 3 spazi, 2 spazi, 1 spazio e nessuno spazio per l'ultima riga. Generalizzando, dobbiamo stampare N - r spazi per ogni riga .

Secondo, confrontando con il primo esempio, ci rendiamo conto che qui abbiamo bisogno di un numero dispari di stelle: 1, 3, 5, 7 ...

Quindi, dobbiamo stampare rx 2-1 stelle per ogni riga .

3.1. Utilizzo di annidati per cicli

Sulla base delle osservazioni precedenti, creiamo il nostro secondo esempio:

public static String printAnIsoscelesTriangle(int N) { StringBuilder result = new StringBuilder(); for (int r = 1; r <= N; r++) { for (int sp = 1; sp <= N - r; sp++) { result.append(" "); } for (int c = 1; c <= (r * 2) - 1; c++) { result.append("*"); } result.append(System.lineSeparator()); } return result.toString(); }

3.2. Utilizzo di un singolo per loop

In realtà, abbiamo un altro modo che consiste solo in un singolo ciclo for : utilizza la libreria Apache Commons Lang 3.

Useremo il ciclo for per iterare sulle righe del triangolo come abbiamo fatto negli esempi precedenti. Quindi, useremo il metodo StringUtils.repeat () per generare i caratteri necessari per ogni riga:

public static String printAnIsoscelesTriangleUsingStringUtils(int N) { StringBuilder result = new StringBuilder(); for (int r = 1; r <= N; r++) { result.append(StringUtils.repeat(' ', N - r)); result.append(StringUtils.repeat('*', 2 * r - 1)); result.append(System.lineSeparator()); } return result.toString(); }

Oppure possiamo fare un bel trucco con il metodo substring () .

Possiamo estrarre i metodi StringUtils.repeat () sopra per creare una stringa di supporto e quindi applicare il metodo String.substring () su di essa. La stringa di supporto è una concatenazione del numero massimo di spazi e del numero massimo di stelle di cui abbiamo bisogno per stampare le righe del triangolo.

Guardando gli esempi precedenti, notiamo che abbiamo bisogno di un numero massimo di N - 1 spazi per la prima riga e un numero massimo di N x 2-1 stelle per l'ultima riga:

String helperString = StringUtils.repeat(' ', N - 1) + StringUtils.repeat('*', N * 2 - 1); // for N = 10, helperString = " *********"

Per esempio, quando N = 5 e r = 3 , abbiamo bisogno di stampare”*****”, che è incluso nel helperString variabile. Tutto quello che dobbiamo fare è trovare la formula giusta per il metodo substring () .

Vediamo ora l'esempio completo:

public static String printAnIsoscelesTriangleUsingSubstring(int N) { StringBuilder result = new StringBuilder(); String helperString = StringUtils.repeat(' ', N - 1) + StringUtils.repeat('*', N * 2 - 1); for (int r = 0; r < N; r++) { result.append(helperString.substring(r, N + 2 * r)); result.append(System.lineSeparator()); } return result.toString(); }

Allo stesso modo, con solo un po 'più di lavoro, potremmo stampare il triangolo capovolto.

4. Complessità

Se guardiamo di nuovo al primo esempio, notiamo un ciclo esterno e un ciclo interno ciascuno con un massimo di N passi. Pertanto, abbiamo una complessità temporale O (N ^ 2) , dove N è il numero di righe del triangolo.

Il secondo esempio è simile: l'unica differenza è che abbiamo due cicli interni, che sono sequenziali e non aumentano la complessità temporale.

Il terzo esempio, tuttavia, utilizza solo un ciclo for con N passaggi. Ma, ad ogni passaggio, chiamiamo il metodo StringUtils.repeat () o il metodo substring () sulla stringa di supporto, ciascuno con complessità O (N) . Quindi, la complessità temporale complessiva rimane la stessa.

Infine, se parliamo dello spazio ausiliario, possiamo rapidamente renderci conto che, per tutti gli esempi, la complessità rimane nella variabile StringBuilder . Aggiungendo l'intero triangolo alla variabile di risultato , non possiamo avere una complessità inferiore a O (N ^ 2) .

Ovviamente, se stampassimo direttamente i caratteri, avremmo una complessità spaziale costante per i primi due esempi. Ma il terzo esempio utilizza la stringa helper e la complessità dello spazio sarebbe O (N) .

5. conclusione

In questo tutorial, abbiamo imparato come stampare due tipi comuni di triangoli in Java.

Per prima cosa, abbiamo studiato il triangolo rettangolo, che è il tipo più semplice di triangolo che possiamo stampare in Java. Quindi, abbiamo esplorato due modi per costruire un triangolo isoscele. Il primo usa solo per i cicli e l'altro sfrutta il metodo StringUtils.repeat () e String.substring () e ci aiuta a scrivere meno codice.

Infine, abbiamo analizzato la complessità temporale e spaziale per ogni esempio.

Come sempre, tutti gli esempi possono essere trovati su GitHub.