Element.java
package com.tutorial;
public interface Element {
}
NumberElement.java
package com.tutorial;
public class NumberElement implements Element {
Double number;
public Double getNumber() {
return number;
}
public NumberElement(String number) {
this.number = Double.parseDouble(number);
}
public String toString()
{
return ((Integer)number.intValue()).toString();
}
}
OperatorElement.java
package com.tutorial;
public class OperatorElement implements Element{
static public enum OperatorType {MULTIPLY, DIVIDE, ADD, SUBTRACT, EXPONENTIAL, OPAREN, CPAREN};
OperatorType type;
Character c;
public OperatorElement(Character operator) {
c = operator;
if(operator == '+')
type = OperatorType.ADD;
else if(operator == '-')
type = OperatorType.SUBTRACT;
else if(operator == '*')
type = OperatorType.MULTIPLY;
else if(operator == '/')
type = OperatorType.DIVIDE;
else if(operator == '^')
type = OperatorType.EXPONENTIAL;
else if(operator == '(')
type = OperatorType.OPAREN;
else if(operator == ')')
type = OperatorType.CPAREN;
}
public String toString()
{
return c.toString();
}
}
Parser.java
package com.tutorial;
import java.util.Collection;
import java.util.Vector;
public class Parser {
Vector <Element> e = new Vector<Element>();
public Collection<Element> Parse(String s)
{
StringBuilder sb = new StringBuilder();
for(int i = 0; i < s.length(); i++)
{
Character c = s.charAt(i);
if(Character.isDigit(c))
sb.append(c);
if(i + 1 < s.length())
{
Character d = s.charAt(i + 1);
if(Character.isDigit(d) == false && sb.length() > 0)
{
e.add(new NumberElement(sb.toString()));
//clears stringbuilder
sb.delete(0, sb.length());
}
}
if(c == '+' || c == '-' || c == '*' || c == '/' || c == '^'
|| c == '(' || c == ')')
e.add(new OperatorElement(c));
}
if(sb.length() > 0)
e.add(new NumberElement(sb.toString()));
return e;
}
}
InfixToPostfix.java
package com.tutorial;
import java.util.Collection;
import java.util.Stack;
import java.util.Vector;
import com.tutorial.OperatorElement.OperatorType;
public class InfixToPostfix {
Vector <Element> converted = new Vector<Element>();
int Precedence(OperatorElement c)
{
if(c.type == OperatorType.EXPONENTIAL)
return 2;
else if(c.type == OperatorType.MULTIPLY || c.type == OperatorType.DIVIDE)
return 3;
else if(c.type == OperatorType.ADD || c.type == OperatorType.SUBTRACT)
return 4;
else
return Integer.MAX_VALUE;
}
public void ProcessOperators(Stack<Element> st, Element element, Element top)
{
while(st.size() > 0 && Precedence((OperatorElement)element) >= Precedence((OperatorElement)top))
{
Element p = st.pop();
if(((OperatorElement)p).type == OperatorType.OPAREN)
break;
converted.add(p);
if(st.size() > 0)
top = st.lastElement();
}
}
public Collection<Element> ConvertFromInfixToPostFix(Collection<Element> e)
{
Vector <Element> stack1 = new Vector<Element>(e);
Stack<Element> st = new Stack<Element>();
for(int i = 0; i < stack1.size(); i++)
{
Element element = stack1.elementAt(i);
if(element instanceof OperatorElement)
{
if(st.empty() ||
((OperatorElement)element).type == OperatorType.OPAREN)
st.push(element);
else
{
Element top = st.lastElement();
if(((OperatorElement)element).type == OperatorType.CPAREN)
ProcessOperators(st, element, top);
else if(Precedence((OperatorElement)element) < Precedence((OperatorElement)top))
st.push(element);
else
{
ProcessOperators(st, element, top);
st.push(element);
}
}
}
else
converted.add(element);
}
//pop all operators in stack
while(st.size() > 0)
{
Element b1 = st.pop();
converted.add(b1);
}
return converted;
}
public String toString()
{
StringBuilder s = new StringBuilder();
for(int j = 0; j < converted.size(); j++)
s.append(converted.elementAt(j) + " ");
return s.toString();
}
}
PostFixEvaluator.java
package com.tutorial;
import java.util.Collection;
import java.util.Stack;
import java.util.Vector;
import com.tutorial.OperatorElement.OperatorType;
public class PostFixEvaluator {
Stack<Element> stack = new Stack<Element>();
NumberElement calculate(NumberElement left, NumberElement right, OperatorElement op)
{
Double temp = Double.MAX_VALUE;
if(op.type == OperatorType.ADD)
temp = left.getNumber() + right.getNumber();
else if(op.type == OperatorType.SUBTRACT)
temp = left.getNumber() - right.getNumber();
else if(op.type == OperatorType.MULTIPLY)
temp = left.getNumber() * right.getNumber();
else if(op.type == OperatorType.DIVIDE)
temp = left.getNumber() / right.getNumber();
else if(op.type == OperatorType.EXPONENTIAL)
temp = Math.pow(left.getNumber(), right.getNumber());
return new NumberElement(temp.toString());
}
public Double Evaluate(Collection<Element> e)
{
Vector <Element> v = new Vector<Element>(e);
for(int i = 0; i < v.size(); i++)
{
Element element = v.elementAt(i);
if(element instanceof NumberElement)
stack.push(element);
if(element instanceof OperatorElement)
{
NumberElement right = (NumberElement) stack.pop();
NumberElement left = (NumberElement) stack.pop();
NumberElement result = calculate(left, right, (OperatorElement)element);
stack.push(result);
}
}
return ((NumberElement)stack.pop()).getNumber();
}
}
CalculatorTest.java
package com.tutorial;
import java.util.Collection;
public class CalculatorTest {
public double Calculate(String s)
{
Parser p = new Parser();
Collection<Element> e = p.Parse(s);
InfixToPostfix i = new InfixToPostfix();
e = i.ConvertFromInfixToPostFix(e);
//debugging
System.out.println("DEBUGGING: " + i.toString());
//
PostFixEvaluator pfe = new PostFixEvaluator();
return pfe.Evaluate(e);
}
public static void main(String[] args) {
CalculatorTest c = new CalculatorTest();
double d = c.Calculate("4+6+9*8-(5*6+9)^2");
System.out.println(d);
}
}