Création d'un triangle avec des boucles for en Java

1. Introduction

Dans ce tutoriel, nous allons explorer plusieurs façons d'imprimer un triangle en Java.

Il existe, naturellement, de nombreux types de triangles. Ici, nous allons en explorer seulement quelques-uns: les triangles droits et isocèles.

2. Construire un triangle droit

Le triangle rectangle est le type de triangle le plus simple que nous allons étudier. Jetons un coup d'œil à la sortie que nous voulons obtenir:

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

Ici, on remarque que le triangle est composé de 5 lignes, chacune ayant un nombre d'étoiles égal au numéro de ligne courant. Bien entendu, cette observation peut être généralisée: pour chaque ligne de 1 à N , nous devons imprimer r étoiles, où r est la ligne courante et N est le nombre total de lignes.

Alors, construisons le triangle en utilisant deux boucles 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. Construire un triangle isocèle

Maintenant, jetons un œil à la forme d'un triangle isocèle:

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

Que voyons-nous dans ce cas? Nous remarquons qu'en plus des étoiles, nous devons également imprimer des espaces pour chaque ligne. Nous devons donc déterminer combien d'espaces et d'étoiles nous devons imprimer pour chaque ligne. Bien entendu, le nombre d'espaces et d'étoiles dépend de la ligne courante.

Tout d'abord, nous voyons que nous devons imprimer 4 espaces pour la première ligne et, lorsque nous descendons le triangle, nous avons besoin de 3 espaces, 2 espaces, 1 espace et aucun espace du tout pour la dernière ligne. En généralisant, nous devons imprimer N - r espaces pour chaque ligne .

Deuxièmement, en comparant avec le premier exemple, nous nous rendons compte qu'ici nous avons besoin d'un nombre impair d'étoiles: 1, 3, 5, 7…

Donc, nous devons imprimer rx 2 - 1 étoiles pour chaque ligne .

3.1. Utilisation de boucles imbriquées pour

Sur la base des observations ci-dessus, créons notre deuxième exemple:

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. Utilisation d'une seule boucle for

En fait, nous avons une autre méthode qui consiste uniquement en une seule boucle for - elle utilise la bibliothèque Apache Commons Lang 3.

Nous allons utiliser la boucle for pour parcourir les lignes du triangle comme nous l'avons fait dans les exemples précédents. Ensuite, nous utiliserons la méthode StringUtils.repeat () afin de générer les caractères nécessaires pour chaque ligne:

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(); }

Ou, nous pouvons faire une astuce avec la méthode substring () .

Nous pouvons extraire les méthodes StringUtils.repeat () ci-dessus pour créer une chaîne d'assistance, puis y appliquer la méthode String.substring () . La chaîne d'assistance est une concaténation du nombre maximum d'espaces et du nombre maximum d'étoiles dont nous avons besoin pour imprimer les lignes du triangle.

En regardant les exemples précédents, nous remarquons que nous avons besoin d'un nombre maximum de N - 1 espaces pour la première ligne et d'un nombre maximum de N x 2 - 1 étoiles pour la dernière ligne:

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

Par exemple, lorsque N = 5 et r = 3 , nous devons afficher «*****», qui est inclus dans la variable helperString . Tout ce que nous devons faire est de trouver la bonne formule pour la méthode substring () .

Voyons maintenant l'exemple complet:

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(); }

De même, avec juste un peu plus de travail, nous pourrions faire imprimer le triangle à l'envers.

4. Complexité

Si l'on regarde à nouveau le premier exemple, on remarque une boucle externe et une boucle interne ayant chacune un maximum de N pas. Par conséquent, nous avons une complexité temporelle O (N ^ 2) , où N est le nombre de lignes du triangle.

Le deuxième exemple est similaire - la seule différence est que nous avons deux boucles internes, qui sont séquentielles et n'augmentent pas la complexité temporelle.

The third example, however, uses only a for loop with N steps. But, at every step, we're calling either the StringUtils.repeat() method or the substring() method on the helper string, each having O(N) complexity. So, the overall time complexity remains the same.

Finally, if we're talking about the auxiliary space, we can quickly realize that, for all examples, the complexity stays in the StringBuilder variable. By adding the entire triangle to the result variable, we cannot have less than O(N^2) complexity.

Of course, if we directly printed the characters, we'd have constant space complexity for the first two examples. But, the third example uses the helper string and the space complexity would be O(N).

5. Conclusion

In this tutorial, we've learned how to print two common types of triangles in Java.

First, we've studied the right triangle, which is the simplest type of triangle we can print in Java. Then, we've explored two ways of building an isosceles triangle. The first one uses only for loops and the other one takes advantage of the StringUtils.repeat() and the String.substring() method and helps us write less code.

Enfin, nous avons analysé la complexité temporelle et spatiale de chaque exemple.

Comme toujours, tous les exemples peuvent être trouvés sur GitHub.