2015-10-15 1 views
1

Je travaille sur l'évaluation d'une expression, et je rencontre des problèmes pour entrer des nombres négatifs. En raison de la structure de mon code, et le fait qu'un opérateur de soustraction et un signe négatif sont le même caractère, mon code ne fonctionne pas pour les nombres négatifs. Y a-t-il un moyen de contourner ce problème?Évaluer le code, en différenciant entre négatif et négatif?

private float evalNoPB(String s) { 

    float tempAns = 0; 
    if (s.contains("*") == false && s.contains("/") == false && s.contains("+") == false && s.contains("-") == false) { 
     return Float.parseFloat(s); 
    } 

    if (s.length() - 1 > 0) { 
     int i; 
     boolean foundPlusMinus = false; 
     for (i = s.length() - 1; i > 0; i--) { 
      if (s.charAt(i) == '+' || s.charAt(i) == '-') { 
       System.out.println(i); 
       foundPlusMinus = true; 
       break; // keep value of i for substrings 
      } 
      foundPlusMinus = false; 
     } 

     if (foundPlusMinus == false) { // for loop went through and did not find + or - 
      for (i = s.length() - 1; i > 0; i--) { 
       if (s.charAt(i) == '*' || s.charAt(i) == '/') { 
        System.out.println(i); 
        break; // keep value of i for substrings 
       } 
      } 
     } 

     String sub1 = s.substring(0, i); 
     System.out.println(sub1); 
     String sub2 = s.substring(i + 1, s.length()); 
     System.out.println(sub2); 

     if (s.charAt(i) == '+') { 
      tempAns = evalNoPB(sub1) + evalNoPB(sub2); 
     } else if (s.charAt(i) == '-') { 
      tempAns = evalNoPB(sub1) - evalNoPB(sub2); 
     } else if (s.charAt(i) == '*') { 
      tempAns = evalNoPB(sub1) * evalNoPB(sub2); 
     } else if (s.charAt(i) == '/') { 
      float divisorCheck = evalNoPB(sub2); 
      if (divisorCheck != 0) { 
       tempAns = evalNoPB(sub1)/evalNoPB(sub2); 
      } else { // cannot divide by 0 
       throw new IllegalArgumentException("cannot divide by 0"); 
      } 
     } 
    } 
    return tempAns; 

} 
+0

Pouvez-vous être plus clair sur votre problème? !!! –

+1

Ce code évalue une expression String. Cela fonctionne pour une chaîne comme '3 * 4 + 5' mais pas pour une chaîne comme' -3 * 4 + 5' car le signe négatif est traité comme un opérateur de soustraction. C'est ce que j'ai besoin de corriger –

+0

Jetez tout cela et cherchez 'l'analyseur d'expression de descente récursive' ou l'algorithme Dijkstra Shunting-yard. Vous ne serez jamais là d'ici. – EJP

Répondre

0

Un travail autour de ne jamais « moins », il suffit d'ajouter des nombres négatifs (si vous devez soustraire quelque chose, il faut multiplier par -1 et l'ajouter avec un autre numéro).

Code Pseudo:

if I come across a - with nothing on either side and not first in string { 
add a + to the left of it 
} 
else { 
if first in string { 
    add 1* to left of it 
} 
do stuff that has to do with *, /, or +. 
} 
if i run across a + { 
    check to see if - is to right of it 
    if so { 
     add together the values but with the value to right of - multiplied by -1 
    } 
    else { 
     add together values 
    } 
} 
+0

Donc, chaque fois que je rencontre un '-', j'aurais besoin de remplacer le terme suivant dans la chaîne par sa valeur négative? –

+0

Selon la situation. À moins que vous ne souhaitiez définir une autre valeur pour représenter un nombre négatif, vous voulez prétendre que vous ne pouvez pas soustraire des nombres, tout ce que vous pouvez faire est ajouter, multiplier et diviser. J'ai mis un pseudo code qui expliquerait un peu la logique derrière ce que je dis, mais vous devez vérifier ce qu'il y a autour du signe - pour savoir quoi en faire. –

+0

Une bonne façon d'y penser est de rendre le plus mathématiquement simple possible. Si vous avez -3 * 4 + 5-9 vous pouvez faire quelque chose comme 1 * -3 * 4 + -9 pour le faire compiler sans erreur. Ayez toujours un opérateur à gauche de - et cela fonctionnera. –

0

La première remarque est que la chaîne peut être analysée à flotter même si elle contient signe moins ("-")

Vérification Alors

if (s.contains("*") == false && s.contains("/") == false && s.contains("+") == false && s.contains("-") == false) { 
    return Float.parseFloat(s); 
} 

est pas tout à fait juste. Il sautera des chaînes comme "-10". Au lieu de cela, je suggère

try { 
    return Float.parseFloat(s); 
} catch (NumberFormatException e) { 
    System.out.println(s + " cannot be parsed to float"); 
} 

et je suggère également de déplacer cette analyse à la fin de la méthode.

La deuxième remarque est de savoir si le signe moins est connecté à la soustraction ou au nombre négatif. Dans l'expression arithmétique simple, vous essayez d'analyser le signe moins qui est connecté au nombre négatif reste soit sur la première place (par exemple -1 + 14) ou juste après un autre soupir (par exemple 17 * -1) Vous devez donc remplacer la boucle

for (i = s.length() - 1; i > 0; i--) { 
     if (s.charAt(i) == '+' || s.charAt(i) == '-') { 
      System.out.println(i); 
      foundPlusMinus = true; 
      break; // keep value of i for substrings 
     } 
     foundPlusMinus = false; 
} 

avec

for (i = s.length() - 1; i >= 0; i--) { 
    if (s.charAt(i) == '+' || s.charAt(i) == '-' && (i != 0 && !isSign(s.charAt(i - 1)))) { 
      System.out.println(i); 
      foundPlusMinus = true; 
      break; // keep value of i for substrings 
    } 
    foundPlusMinus = false; 
} 

private boolean isSign(char c) { 
    return c == '+' || c == '-' || c == '*' || c =='/'; 
} 

Notez que je passe maintenant à 0 (i> = 0) et si on trouve signe moins, nous vérifions que le caractère précédent (si elle existe) est pas un signe. Dans ce cas, c'est un signe de soustraction.

La dernière remarque est que cet algorithme récursif est assez naïf et lorsque des crochets apparaissent, vous aurez besoin de quelque chose de plus compliqué. Vous pouvez trouver des informations sur les algorithmes avancés par exemple ici: http://www.sunshine2k.de/coding/java/SimpleParser/SimpleParser.html