问题
I am working on evaluating an expression, and I am running into trouble inputting negative numbers. Due to the structure of my code, and the fact that a subtraction operator and a negative sign are the same character, my code doesn't work for negative numbers. Is there a way to work around this?
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;
}
回答1:
One work around is don't ever 'minus', just add negative numbers (if you need to subtract something, multiply it by -1 and add it with another number).
Pseudo code:
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
}
}
回答2:
The first remark is that string can be parsed to float even if it contains minus sign ("-")
So checking
if (s.contains("*") == false && s.contains("/") == false && s.contains("+") == false && s.contains("-") == false) {
return Float.parseFloat(s);
}
is not quite right. It will skip strings like "-10". Instead of that I would suggest
try {
return Float.parseFloat(s);
} catch (NumberFormatException e) {
System.out.println(s + " cannot be parsed to float");
}
and I would also suggest moving this parsing to the end of the method.
Second remark is about finding out if minus sign is connected to subtraction or negative number. In the simple arithmetic expression you trying to parse minus sign that is connected to negative number stays either on the first place (e.g -1+14) or right after another sigh (e.g 17*-1) So you need to substitute loop
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;
}
with
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 =='/';
}
Note that i now goes down to 0 (i>=0) and if we find minus sign we check that previous character (if it exist) is not a sign. In that case it is subtraction sign.
Last remark is that this recursive algorithm is quite naive and when brackets show up you will need something more complicated. You can find information about advanced algorithms for example here: http://www.sunshine2k.de/coding/java/SimpleParser/SimpleParser.html
来源:https://stackoverflow.com/questions/33158960/evaluate-code-differentiating-between-minus-and-negative