Ex a réaliser avec erreur inconnue

Fermé
DjNellio Messages postés 9 Date d'inscription vendredi 7 octobre 2016 Statut Membre Dernière intervention 19 mars 2017 - Modifié par baladur13 le 7/10/2016 à 18:44
DjNellio Messages postés 9 Date d'inscription vendredi 7 octobre 2016 Statut Membre Dernière intervention 19 mars 2017 - 7 oct. 2016 à 20:03
Salut à tous ! Je me décide enfin de poster dans ce forum après m'en être servi tant de fois! ( Déjà merci la commu ! )



Alors ! Je dois réaliser une calculatrice simple avec quelques conditions . A l'heure actuelle , nous avons appris que peu de choses . Voici les conditions :

Ecrire un programme capable de calculer une expression mathématique simple.
Cette calculatrice ne comprend que les nombres entiers et les opérateurs mathématiques + - x :
La calculatrice respecte néanmoins l’ordre des opérateurs.
L’utilisateur entre au clavier une expression mathématique: 5 + 3 x 2 - 1
Cet expression est mémorisée dans un String
Le programme passe cette expression à une fonction calculer.
La fonction calculer évalue l’expression et retourne le résultat sous forme d’un String
Si l’expression est correcte, le résultat correspondra à la valeur calculée, sinon un message d’erreur est retournée
Exemple
Expression: 5 + 3 x 2 - 1
Résultat: 10
Expression: 5 / 0
Résultat: Division par zéro impossible
Expression: 8.1 x 10
Résultat: Symbole non reconnu


Voici le code que j'ai déjà effectué ( le cas du 8.1 x 10 n'est pas encore geré :) ):


import java.util.ArrayList;
import java.util.Scanner;

public class Exp{
    
    public static void main(String args[]) {
     
     // Déclarations
     
     boolean b1;
     int prov ;
     int j ;
     int k ;
     int l ;
     int con ;
     String test ;
     char c ;
   
     
     // Initialisations
     
     String rep = null ;
     String cas = "caca" ;
     
     // Récupération de la chaine et mise en place du tableau et ArrayList

     Scanner kb = new Scanner (System.in);
  System.out.println ("Entrez une expression mathématique simple");
  String exp = kb.nextLine();
  int x = exp.length();
  
  // Agissement du séparateur
  final String sep = " ";
  String mots[] = exp.split(sep);
  l =  mots.length;
  ArrayList<String> li = new ArrayList<String>() ;   //typer
  b1 = true;
  
  
   for (int i = 0; i < mots.length; i++) {
    li.add(i,mots[i]) ;
    System.out.println(li.get(i));
   }
    
        for (int i =0 ; i < mots.length; i++) 
        {

         test = li.get(i);
         c =li.get(i).charAt(0);
         
         System.out.println(c);
         b1 = Character.isDigit(c);
         System.out.println(b1);
         if((b1 = true)){
          
         
         if ((test=="+")||(test=="-")||(test=="*")||(test=="/")); //
         
         {

          
          prov = 0;
  
          if(mots[i] .equals ("/"))
          
          {  
           if(mots[i+1].equals (0)){
            System.out.println("Division par 0");
           }
           else {

                 j = Integer.parseInt(mots[i-1]);
           k = Integer.parseInt(mots[i+1]);
                 prov = j / k ;
                 rep = ""+prov  ;
                 li.add(i-1, rep);
                 li.remove(i);
                 li.remove(i+1);
                 if (li.size() == 1 )
                 {
                  System.out.println ("La réponse : " +li.get(0) );
                 }
          }
          }
               
          if(mots[i] .equals ("*"))
          {
           j = Integer.parseInt(mots[i-1]);
        k = Integer.parseInt(mots[i+1]);
        prov = j * k ;
        rep = ""+prov  ;
        li.add(i-1, rep);
        li.remove(i);
               li.remove(i+1);
        if (li.size() == 1 )
        {
              System.out.println ("La réponse : " +li.get(0));
              }
               
         
          }
            
          if(mots[i] .equals ("+"))
          { 
           j = Integer.parseInt(mots[i-1]);
           k = Integer.parseInt(mots[i+1]);
           prov = j + k ;
           rep = ""+prov;
              rep = ""+prov  ;
              li.add(i-1, rep);
              li.remove(i);
               li.remove(i+1);
              if (li.size() == 1  )
             {
              System.out.println ("La réponse : " +li.get(0));
             }
          }
            if(mots[i] .equals ("-"))
            { 
             j = Integer.parseInt(mots[i-1]);        
             k = Integer.parseInt(mots[i+1]);
             prov = j - k ;
             rep = ""+prov  ;
             li.add(i-1, rep);
             li.remove(i);
          li.remove(i+1);
             if (li.size() == 1 )
             {
              System.out.println ("La réponse : " +li.get(0));
             }
            
            }
           
            else
            {
             System.out.println("Caractère interdit");
            }
            }   
        
         
         }
        }
    }
}




( JE SAIS , QUELQUES PRINTLN SONT LA POUR DES TESTS )



La logique que j'ai pensé est que quand on entre la chaine , le programme va détecter les * et / en premier , le i étant le signe repéré , que le i-1 est remplacé par le résultat de l'op et que le i et i+1 sont effacé


Seulement , quand l'utilisateur tape 5 + 2 ( le séparateur étant l'espace ) j'obtiens :

java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at Exp.main(Exp.java:48)


La ligne 48 étant : test = li.get(i);

et lors d'une saisie 5+2 sans espace : le résultat est d'office carac interdit


Serait-ce un probleme du booléen que j'utilise?


Comment régler ses problèmes , je ne trouve vraiment pas les amis :(


D'avance merci!

EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.
A voir également:

2 réponses

KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
7 oct. 2016 à 19:29
Bonjour,

Le problème c'est que tu fais des li.remove donc la taille de la liste peut changer et tu n'auras pas toujours li.size() == mots.length

Du coup avec ton
for (int i =0 ; i < mots.length; i++)
tu peux te retrouver à un moment avec
i >= li.size()
et c'est ça qui fait planter ton
li.get(i);
...

De manière générale quelques remarques :
1) Tu n'as pas besoin de mettre des espaces dans tes opérations, et je t'invite à les simplifier afin qu'il n'y en ait pas, ou à les interdire au même titre que le point dans 8.1
2) Tu as mis tout ton code dans la méthode main, c'est illisible et compliqué, tu gagnerais à découper ton code en méthodes intermédiaires
3) Est-ce que tu connais la notation polonaise ? C'est très pratique dans ce genre de problème.
Par décomposition tu as
5+3x2-1=(5+3x2)-1=(5+(3x2))-1
ce qui donne en notation polonaise
- 1 (5+(3x2))
puis
- 1 + 5 (3x2)
et au final
- 1 + 5 x 3 2
. Cette transcription permet ensuite d'utiliser une pile, car si tu lis de droite à gauche, tu vas consommer deux opérandes 2 et 3, l'appliquer à un opérateur x, calculer le résultat 6 et le remettre dans la pile, ce qui donne
- 1 + 5 6
et en recommençant tu consommes deux opérandes 6 et 5 dans la pile, un opérateur + et tu remets le résultat 11, on a donc
- 1 11
puis pareil on consomme 11, 1 et - on calcule 10 ce qui devient notre résultat final puisqu'il n'y a rien d'autre.
0
DjNellio Messages postés 9 Date d'inscription vendredi 7 octobre 2016 Statut Membre Dernière intervention 19 mars 2017
7 oct. 2016 à 19:42
Effectivement ! Comment modifier le compteur alors ? Un deuxieme compteur qui s'incrémente de 2 ( car deux cases supp )

1 ) les espaces sont obligés par l'exercise ( Fait expres pour pouvoir avoir un séparateur facile )

2 ) Obligé aussi car on n'as pas encore vu les méthodes ( Ca fait que deux semaines que l'on apprends a raison de 3 h / sem)

3 ) Non :/
0
DjNellio Messages postés 9 Date d'inscription vendredi 7 octobre 2016 Statut Membre Dernière intervention 19 mars 2017
7 oct. 2016 à 19:49
Je viens de me rendre compte , pourquoi pas utiliser le li.size() ?
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
7 oct. 2016 à 19:52
J'avoue ne pas avoir lu tout le code, juste la partie qui posait problème, mais c'est vrai que li.size() serait plus adapté, même si je ne suis pas sûr qu'une boucle for soit vraiment pertinente dans ton cas...
0
DjNellio Messages postés 9 Date d'inscription vendredi 7 octobre 2016 Statut Membre Dernière intervention 19 mars 2017
7 oct. 2016 à 19:52
C'est normal t'en fais pas , déjà merci de m'aider ! :D le Li.size enleve le probleme effectivement :-)
0
DjNellio Messages postés 9 Date d'inscription vendredi 7 octobre 2016 Statut Membre Dernière intervention 19 mars 2017
7 oct. 2016 à 19:52
L'erreur maintenant , c'est que peut importe le résultat du Booléen , il passe d'office dans le cas caract interdit en cas de chiffre. Les signe mathématiques passent.
0
DjNellio Messages postés 9 Date d'inscription vendredi 7 octobre 2016 Statut Membre Dernière intervention 19 mars 2017
7 oct. 2016 à 19:53
Exemple :

Entrez une expression mathématique simple
5 + 2 + 3 + 4
5
+
2
+
3
+
4
5
true
Caractère interdit
+
false
Caractère interdit
+
false
Caractère interdit
3
true
Caractère interdit
4
true
Caractère interdit
0
DjNellio Messages postés 9 Date d'inscription vendredi 7 octobre 2016 Statut Membre Dernière intervention 19 mars 2017
7 oct. 2016 à 20:03
D'ailleurs il teste 5 , le "+" , mais pas le deux et saute le dernier "+"
0