patternjavaMinor
Evaluating an expression with integers, +, and *, as well as -, /
Viewed 0 times
expressionwithwellandintegersevaluating
Problem
There is a job interview question, and the source of the question is here.
The solution is pretty simple. We just need to split the input string by + and then by *. Then we compute products in a nested loop and sum up all the products.
But what if I was asked the following question after solving the initial problem:
OK. What would you do if you needed to support not only
The quick solution I thought up is this:
```
package careepcup.fb;
public class Main {
// http://www.careercup.com/question?id=4911380140392448
public static void main(String[] args) {
// An equation with +, -, /, *
String anotherEquation = "154+8*9+16/8-9"; // 85
double another = computeAnother(anotherEquation);
System.out.println(another);
}
static double computeAnother(String equation) {
double result = 0.0;
String noMinus = equation.replace("-", "+-");
String[] byPluses = noMinus.split("\\+");
for (String multipl : byPluses) {
String[] byMultipl = multipl.split("\\*");
double multiplResult = 1.0;
for (String operand : byMultipl) {
if (operand.contains("/")) {
String[] division = operand.split("\\/");
The solution is pretty simple. We just need to split the input string by + and then by *. Then we compute products in a nested loop and sum up all the products.
public class Main {
// http://www.careercup.com/question?id=4911380140392448
public static void main(String[] args) {
String equation = "1*5*4+8*9+16";
int result = compute(equation);
System.out.println(result);
}
static int compute(String equation) {
int result = 0;
String []byPluses = equation.split("\\+");
for (String multipl : byPluses) {
String []byMultipl = multipl.split("\\*");
int multiplResult = 1;
for (String operand : byMultipl) {
multiplResult *= Integer.parseInt(operand);
}
result += multiplResult;
}
return result;
}
}But what if I was asked the following question after solving the initial problem:
OK. What would you do if you needed to support not only
+ and * but also - and /?The quick solution I thought up is this:
```
package careepcup.fb;
public class Main {
// http://www.careercup.com/question?id=4911380140392448
public static void main(String[] args) {
// An equation with +, -, /, *
String anotherEquation = "154+8*9+16/8-9"; // 85
double another = computeAnother(anotherEquation);
System.out.println(another);
}
static double computeAnother(String equation) {
double result = 0.0;
String noMinus = equation.replace("-", "+-");
String[] byPluses = noMinus.split("\\+");
for (String multipl : byPluses) {
String[] byMultipl = multipl.split("\\*");
double multiplResult = 1.0;
for (String operand : byMultipl) {
if (operand.contains("/")) {
String[] division = operand.split("\\/");
Solution
@tim has covered a bunch of what I was going to add, but here are some additional points:
You should anticipate having whitespace in the input. A "simple" replace-all would suffice:
Your solution of converting
Bug: Your system will fail on things like:
Your inner workings of the
Operators of equal precedence should be handled together. treating
I would suggest using a smarter split expression, one that splits on the gaps between the operators and the values...:
With the above regex, you will get for example:
The way the regex works is that it looks for two things (the regex is in two parts - using "lookaround" expressions)....
Put them together with an or condition, it says: split the input on the gaps before and after /
Now, you can just initialize the result to index-1, and then loop through the rest.... :
You should anticipate having whitespace in the input. A "simple" replace-all would suffice:
equation = equation.replaceAll("\\s+", "");Your solution of converting
- to +- is novel, and effective, but it really should have a comment on it explaining that you are going to re-split the String and parse the new - as part of the integer, rather than as an operator. Leaving it as it is required some detective work on how it functions.Bug: Your system will fail on things like:
1 + 2 * -3 (ignoring the whitespace).Your inner workings of the
* and / is a bit messy, though. A logical progression for your challenge would be to add, say, a % operator.... which would require a complicated change.Operators of equal precedence should be handled together. treating
specially when compared to / makes it awkward because you have to test all combinations inside the breakdown....I would suggest using a smarter split expression, one that splits on the gaps between the operators and the values...:
String[] parts = operand.split("(?=[/*])|(?<=[/*])");With the above regex, you will get for example:
1/2*773 -> [1, /, 2, *, 773]The way the regex works is that it looks for two things (the regex is in two parts - using "lookaround" expressions)....
(?=[/])- A positive zero-width look-ahead - This says: find any gap between two characters where the next character is a/or.
(?
Put them together with an or condition, it says: split the input on the gaps before and after /
or *`.Now, you can just initialize the result to index-1, and then loop through the rest.... :
double result = Double.parseDouble(parts[0]);
for (int i = 1; i < parts.length; i += 2) {
String op = parts[i];
double val = Double.parseDouble(parts[i+1]);
switch (op) {
case "*" :
result *= val;
break;
case "/" :
result /= val;
break;
}
}
return result;Code Snippets
equation = equation.replaceAll("\\s+", "");String[] parts = operand.split("(?=[/*])|(?<=[/*])");1/2*773 -> [1, /, 2, *, 773]double result = Double.parseDouble(parts[0]);
for (int i = 1; i < parts.length; i += 2) {
String op = parts[i];
double val = Double.parseDouble(parts[i+1]);
switch (op) {
case "*" :
result *= val;
break;
case "/" :
result /= val;
break;
}
}
return result;Context
StackExchange Code Review Q#84763, answer score: 9
Revisions (0)
No revisions yet.