Implémenter quelque chose comme une pile en Java

introduction

Pour une raison quelconque, j'ai soudainement décidé de créer et d'expliquer un programme de type pile pour ceux qui ont commencé à apprendre Java. Cependant, en raison de contraintes de temps, je n'ai pas pu l'expliquer du tout, je vais donc continuer l'explication dans cet article en tant que supplément et mission Qiita.

Le public cible est celui des nouveaux utilisateurs de Java. Pour être plus précis, je suppose que j'ai appris les bases des types de données et des tableaux via Hello World, et juste après avoir appris à écrire des instructions if, for et while.

Cependant, je pense qu'il est difficile d'implémenter soudainement une pile (quelque chose comme ça), donc dans le chapitre 1, nous ne créerons que le cadre minimum, et dans le chapitre 2 et plus tard, nous ajouterons séquentiellement les fonctions requises sous forme de pile. Nous allons l'implémenter en plus. Donc, si vous codez dans l'ordre du chapitre 1, vous devriez être capable de créer une pile (quelque chose comme ça) sans trop de confusion.

En tant qu'environnement de développement, paiza.io sera utilisé. Comme le titre l'indique, le langage est Java.

Alors, s'il vous plaît, restez avec moi pendant un moment.

Chapitre 0 À propos de Stack

Une pile est l'une des structures de données et possède un mécanisme (LIFO: Last In First Out) pour sortir la dernière. Imaginez un ascenseur. Si vous ne tenez pas compte des manières des travailleurs, lorsque vous montez dans l'ascenseur, commencez par l'arrière. Et en descendant de l'ascenseur, descendez de la personne près de la porte, c'est-à-dire la personne qui est montée en dernier.

Dans cet article, nous allons créer un programme de type pile qui pousse (stocke) les entiers d'entrée dans un tableau qui a le rôle d'une pile, et apparaît (sorties) dans l'ordre à partir du dernier entier d'entrée. Le but ultime est de répondre aux exigences suivantes:

Implémentons-le petit à petit à partir du chapitre 1.

Chapitre 1 Traitement des entrées

Dans ce chapitre, commençons par les éléments relativement simples suivants.

Allez sur paiza.io et cliquez sur "Essayer la création de code (gratuit)". Au début, vous pouvez voir des exemples d'autres langages tels que PHP, mais dans ce cas, choisissez Java. Vous devriez voir un programme simple contenant la méthode println comme suit:

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        
        System.out.println("XXXXXXXX");
    }
}

Maintenant, afin d'accepter l'entrée de chaînes de caractères et d'entiers, nous le recevrons une fois en tant que type String et le convertirons en type int uniquement lorsqu'il est traité comme un entier. Maintenant, essayez d'écrire un programme qui conserve la chaîne de caractères d'entrée stockée dans le type String pour le moment. Ajoutez également un processus pour afficher «Votre entrée est [chaîne de caractères d'entrée]» pour vérifier si l'entrée est acceptée correctement lorsqu'elle est exécutée. Si vous pouvez l'écrire, vérifions l'exemple de réponse 1-1 ci-dessous.

<détails>

Exemple de réponse 1-1 (Cliquez pour ouvrir) </ summary>

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        while (true) {
            String input = sc.nextLine();
            System.out.println("Your input is [" + input + "]");
        }
    }
}

Essayons-le. Dans paiza.io, au lieu de taper à partir de l'invite de commande, vous devez sélectionner l'onglet d'entrée et écrire tout ce que vous voulez taper dans la fenêtre qui apparaît. Ainsi, lorsque vous cliquez sur l'onglet d'entrée, écrivez comme suit.

push 1
push 2
push 3
end

Une fois que vous avez fait cela, il est temps de le faire vraiment. Cela créera un onglet appelé Erreur d'exécution avec le message "Aucune ligne trouvée". La raison en est que la condition de répétition de l'instruction while est vraie, donc le processus doit se répéter pour toujours. Même si j'ai accepté la contribution jusqu'à la fin, j'ai essayé de recevoir plus de commentaires, alors on m'a dit «Plus rien». En fait, si vous cliquez sur l'onglet de sortie, vous pouvez voir qu'il accepte jusqu'à "fin" correctement.

Maintenant, considérons les éléments suivants.

--Le programme se termine lorsque "fin" est entré.

Pour déterminer si la chaîne saisie est égale à "end", vous pouvez utiliser la méthode equals fournie par l'objet de classe String. Veuillez vérifier vous-même l'utilisation détaillée et écrire un processus pour sortir de la boucle de l'instruction while lorsque "end" est entré. Si vous pouvez l'écrire, vérifions l'exemple de réponse 1-2 ci-dessous.

<détails>

Exemple de réponse 1-2 (Cliquez pour ouvrir) </ summary>

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        while (true) {
            String input = sc.nextLine();
            System.out.println("Your input is [" + input + "]");
            if (input.equals("end")) {
                break;
            }
        }
    }
}

Essayez-le. Après avoir accepté "end", j'ai quitté la boucle de l'instruction while et le programme a pu se terminer normalement, il n'y a donc pas d'erreur d'exécution. Le processus d'entrée est maintenant OK.

Chapitre 2 Traitement push

Dans ce chapitre, vous implémenterez les éléments suivants:

--Lorsque "push integer" est entré, ajoutez l'entier au début du tableau. Si 5 ont déjà été saisis, une "erreur de poussée" est émise.

Préparons un tableau de type int qui agit comme une pile. Le nom du tableau doit être stack. De plus, lors de la déclaration d'un tableau, n'écrivez pas directement 5 pour spécifier le nombre d'éléments. Au lieu de cela, affectez 5 à la variable de type int N à l'avance et utilisez N lors de la déclaration du tableau. Ceux-ci sont écrits avant l'instruction while.

Ensuite, réfléchissons à la façon de gérer l'entrée de "push integer". Puisque la chaîne de caractères d'entrée est push, un espace demi-largeur et un entier, permettent d'abord de juger qu'il s'agit d'une commande push en ne regardant que les 4 premiers caractères. Pour ce faire, utilisez la méthode substring fournie par la classe String.

De plus, puisque seuls les entiers sont extraits de la chaîne de caractères d'entrée, utilisons également la méthode de fractionnement fournie dans la classe String pour les séparer en push et entiers. Toutefois, comme l'entier est traité comme une chaîne de caractères simplement en le divisant, utilisez la méthode parseInt de la classe Integer pour convertir la chaîne de caractères en type int. Utilisez la méthode parseInt comme suit.

int number = Integer.parseInt(string);

Enfin, considérons le processus de détermination du numéro de la pile de tableaux lors de la poussée d'un entier. Vous pourriez penser que le tableau a à la fois l'avant et l'arrière, mais ici nous décidons que le 0ème élément est l'avant et le N $ - $ 1 ($ = $ 4) e élément est l'arrière. .. Autrement dit, les nombres entiers sont stockés du N $ - $ 1er à l'arrière au 0ème au premier plan. Cependant, si l'entier est déjà stocké jusqu'au 0, il est nécessaire de générer un message d'erreur, veuillez donc l'écrire avec prudence. Si vous pouvez l'écrire, vérifions l'exemple de réponse 2 ci-dessous.

<détails>

Exemple de réponse 2 (cliquez pour ouvrir) </ summary>

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        int N = 5;
        int[] stack = new int[N];
        int indexPointer = N;
        
        while (true) {
            String input = sc.nextLine();
            System.out.println("Your input is [" + input + "]");
            if (input.equals("end")) {
                break;
            } else if (input.substring(0, 4).equals("push")) {
                if (indexPointer >= 1 && indexPointer <= N) {
                    String[] commands = input.split(" ");
                    int number = Integer.parseInt(commands[1]);
                    indexPointer --;
                    stack[indexPointer] = number;
                    System.out.println(number + " pushed. index:" + indexPointer);
                } else {
                    System.out.println("push error.");
                }
            }
        }
    }
}

Je vais compléter un peu. Nous avons préparé une nouvelle variable de type int indexPointer pour savoir dans quel élément du tableau l'entier est stocké. Lors du traitement push, il est déterminé si un entier peut être stocké un avant l'élément qui a été visualisé immédiatement avant, c'est-à-dire si indexPointer est __now__1 ou plus et N ou moins. Si c'est vrai, décrémentez indexPointer de 1 et stockez l'entier à la place de cette valeur. Pour ce processus, la valeur initiale lors de la déclaration d'indexPointer doit être N.

Maintenant, testons un peu pour voir si le processus jusqu'à présent est correct. Sélectionnez l'onglet de saisie et écrivez comme suit.

push 1
push 2
push 3
push 4
push 5
push 6
end

Je vais essayer.

Your input is [push 1]
1 pushed. index:4
Your input is [push 2]
2 pushed. index:3
Your input is [push 3]
3 pushed. index:2
Your input is [push 4]
4 pushed. index:1
Your input is [push 5]
5 pushed. index:0
Your input is [push 6]
push error.
Your input is [end]

Les entiers sont stockés dans l'ordre à partir de l'arrière du tableau, et après avoir stocké 5 d'entre eux, un message d'erreur s'affiche.

Chapitre 3 Traitement des pop

Si vous êtes arrivé jusqu'ici, la pile est presque terminée. Dans le chapitre précédent, nous avons décidé d'utiliser la variable indexPointer pour saisir le numéro de l'élément dans le tableau. Cette variable peut être utilisée pour le traitement des pop en l'état. Si vous pouvez l'écrire, vérifions l'exemple de réponse 3 ci-dessous.

Exemple de réponse 3 (Cliquez pour ouvrir)
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        int N = 5;
        int[] stack = new int[N];
        int indexPointer = N;
        
        while (true) {
            String input = sc.nextLine();
            System.out.println("Your input is [" + input + "]");
            if (input.equals("end")) {
                break;
            } else if (input.length() >= 4 && input.substring(0, 4).equals("push")) {
                if (indexPointer >= 1 && indexPointer <= N) {
                    String[] commands = input.split(" ");
                    int number = Integer.parseInt(commands[1]);
                    indexPointer --;
                    stack[indexPointer] = number;
                    System.out.println(number + " pushed. index:" + indexPointer);
                } else {
                    System.out.println("push error.");
                }
            } else if (input.equals("pop")) {
                if (indexPointer >= 0 && indexPointer < N) {
                    System.out.println(stack[indexPointer] + " poped. index:" + indexPointer);
                    indexPointer ++;
                } else {
                    System.out.println("pop error.");
                }
            }
        }
    }
}

Qu'est-ce que tu penses. Je pense que c'était un peu plus facile que le processus push. Maintenant, essayez de taper ce qui suit dans l'onglet Entrée:

pop
push 1
push 2
push 3
pop
pop
pop
push 4
push 5
push 6
push 7
push 8
push 9
end

Je vais essayer.

Your input is [pop]
pop error.
Your input is [push 1]
1 pushed. index:4
Your input is [push 2]
2 pushed. index:3
Your input is [push 3]
3 pushed. index:2
Your input is [pop]
3 popped. index:2
Your input is [pop]
2 popped. index:3
Your input is [pop]
1 popped. index:4
Your input is [push 4]
4 pushed. index:4
Your input is [push 5]
5 pushed. index:3
Your input is [push 6]
6 pushed. index:2
Your input is [push 7]
7 pushed. index:1
Your input is [push 8]
8 pushed. index:0
Your input is [push 9]
push error.
Your input is [end]

Correctement, les poussées 1, 2 et 3 sont sautées dans l'ordre inverse. En outre, si vous essayez de pop même si aucun entier n'est stocké, ou si vous essayez de pousser même si 5 entiers sont déjà stockés, un message d'erreur sera affiché.

en conclusion

Cette fois, j'ai implémenté une pile simple en utilisant la syntaxe Java de base. Vous pouvez en fait implémenter une file d'attente avec juste quelques changements dans le programme ci-dessus, donc si vous avez le temps, essayez-le.

Merci pour la lecture.

Recommended Posts