patternjavaMinor
Cleaning up Reverse Polish Notation evaluator
Viewed 0 times
polishreverseevaluatornotationcleaning
Problem
I was wondering if anyone had some general clean up advice on my code. I believe that more helper functions would be my case but I could be wrong. 30 lines maximum per method is my rule. I can't seem to figure out how to clean this up more, though.
Sample Input:
(1/3) (1/5) - (40/1) * #
(2/3) B * #
Sample Output
Expression 1 is: (1/3)(1/5)-(40/1)*
The value is: (16/3)
Intermediate results: (2/15)(16/3)
Expression 2 is: (2/3)B
Invalid Expression
Intermediate results:
```
import java.util.Scanner;
public class RpnEvaluator
{
private final int MAX_TOKEN = 100;
private Scanner stdin = new Scanner(System.in);
private Queue myQueue = new Queue(MAX_TOKEN);
private Stack myStack = new Stack(MAX_TOKEN);
public void run() throws java.io.IOException
{
int count = 1;
Fraction myInterMid;
while(stdin.hasNext())
{
runOnce(count++);
System.out.print("Intermediate results: ");
while(!myQueue.isEmpty())
{
myInterMid = (Fraction)myQueue.remove();
System.out.print(myInterMid.toString());
}
System.out.println();
clear(myStack, myQueue);
}
System.out.println("Normal Termination of Program 3.");
}
private boolean isOperator(String input)
{
String[] oprtr = {"+", "-", "*"};
for(String choice: oprtr)
if(choice.equals(input))
return true;
return false;
}
private boolean isOperand(String input)
{
if(input.charAt(0) == '(')
return true;
return false;
}
private Fraction runOperation(String choice, Fraction op2, Fraction op1)
{
Fraction newFract = new Fraction();
switch (choice)
{
case "*":
newFract = new Fraction(op1.times(op2));
break;
case "+":
newFract = new Fraction(op1.plus(op2));
break;
case "-":
newFract = new Fr
Sample Input:
(1/3) (1/5) - (40/1) * #
(2/3) B * #
Sample Output
Expression 1 is: (1/3)(1/5)-(40/1)*
The value is: (16/3)
Intermediate results: (2/15)(16/3)
Expression 2 is: (2/3)B
Invalid Expression
Intermediate results:
```
import java.util.Scanner;
public class RpnEvaluator
{
private final int MAX_TOKEN = 100;
private Scanner stdin = new Scanner(System.in);
private Queue myQueue = new Queue(MAX_TOKEN);
private Stack myStack = new Stack(MAX_TOKEN);
public void run() throws java.io.IOException
{
int count = 1;
Fraction myInterMid;
while(stdin.hasNext())
{
runOnce(count++);
System.out.print("Intermediate results: ");
while(!myQueue.isEmpty())
{
myInterMid = (Fraction)myQueue.remove();
System.out.print(myInterMid.toString());
}
System.out.println();
clear(myStack, myQueue);
}
System.out.println("Normal Termination of Program 3.");
}
private boolean isOperator(String input)
{
String[] oprtr = {"+", "-", "*"};
for(String choice: oprtr)
if(choice.equals(input))
return true;
return false;
}
private boolean isOperand(String input)
{
if(input.charAt(0) == '(')
return true;
return false;
}
private Fraction runOperation(String choice, Fraction op2, Fraction op1)
{
Fraction newFract = new Fraction();
switch (choice)
{
case "*":
newFract = new Fraction(op1.times(op2));
break;
case "+":
newFract = new Fraction(op1.plus(op2));
break;
case "-":
newFract = new Fr
Solution
Reverse Polish Notation does not need parentheses, so that should actually be invalid input and should not be checked.
To determine if something is an operand you should be able to use
Instead of terminating input with
I'm not sure what the purpose of having
I would recommend reading up on RPN to understand it more (the Wikipedia page has an algorithm for interpreting RPN) and see if that gives you ideas on how you might rethink your approach.
Edit: Assuming that the input format and output values are requirements, there are several things you can do to improve the code.
To determine if something is an operand you should be able to use
stdin.hasNextInt(). If that is false, then you should be able to use stdin.next() to get whatever the operator is. This could greatly simplify your type checking.Instead of terminating input with
# you should just check for newlines.I'm not sure what the purpose of having
myQueue is. You should only need a stack for processing RPN.I would recommend reading up on RPN to understand it more (the Wikipedia page has an algorithm for interpreting RPN) and see if that gives you ideas on how you might rethink your approach.
Edit: Assuming that the input format and output values are requirements, there are several things you can do to improve the code.
MAX_TOKENshould beprivate static final.
- You should rename your methods to better describe what they do.
runOnce()is called in a loop, so it is not called once, and it doesn't explain what it does. I would recommend something likeprocessNextCalculation().doTypeCheck(),throwLine()andcheckMessageValid()should also be renamed.
- You should move the output in
checkMessageValid()to be in the same place as where you output the intermediate results. You will need to change some return values to propagate the results upward.
isOperand()can be reduced toreturn input.charAt(0) == '(';
- In
run()you don't usemyInterMidelsewhere so you can remove references to it and simplySystem.out.println(myQueue.remove());
- You should try to be consistent about using
myas a prefix. Typically, it implies that the variable is an instance member variable, but you also use it for variables within methods. That is definitely confusing.
- I don't know what is in your
Fractionclass, but I imagine that thetimes(),plus(), andminus()methods are returningFractions, so you don't need tonewone up from the result.
- You don't need to declare
op1andop2inrunOnce(), since you can just pass two nulls todoTypeCheck(). For that matter, you don't need to even have parameters fordoTypeCheck(). Once you've done that, you should bring the rest of the method up torun()so you can keep your text output in the same place.
- Since you can't have both
isOperator()andisOperand()be true, you don't need to check both in your first if condition indoTypeCheck().
- You don't need to check
myStack.isEmpty()twice, you should be able to check ifmyStack.size()is less than two. If your implementation ofStackdoesn't have asize()method, well...I feel bad for you.
- Whenever
myStack.isEmpty()is true, you can break out of the loop and your failure case will still show correctly.
- You only need one
FractioninprocessOperand()and you can initialize it on the same line as you declare it.
Context
StackExchange Code Review Q#43984, answer score: 8
Revisions (0)
No revisions yet.