Element.scala
package calculator
trait Element {
}
NumberElement.scala
package calculator
class NumberElement(numberArg: String) extends Element {
var number: Double = numberArg.toDouble
def getNumber = number
override def toString() : String = {
return number.toString()
}
}
OperatorElement.scala
package calculator
sealed trait OperatorType
case object MULTIPLY extends OperatorType
case object DIVIDE extends OperatorType
case object ADD extends OperatorType
case object SUBTRACT extends OperatorType
case object EXPONENTIAL extends OperatorType
case object OPAREN extends OperatorType
case object CPAREN extends OperatorType
case object NULL extends OperatorType
class OperatorElement(operator: Character) extends Element {
var type1 : OperatorType = NULL
var c : Character = operator
if(operator == '+')
type1 = ADD
else if(operator == '-')
type1 = SUBTRACT
else if(operator == '*')
type1 = MULTIPLY
else if(operator == '/')
type1 = DIVIDE
else if(operator == '^')
type1 = EXPONENTIAL
else if(operator == '(')
type1 = OPAREN
else if(operator == ')')
type1 = CPAREN
override def toString() : String = {
return c.toString()
}
}
Parser.scala
package calculator
import scala.collection.mutable.ArrayBuffer
class Parser {
def Parse(s: String) : ArrayBuffer[Element] =
{
var e = new ArrayBuffer[Element]()
var sb = new StringBuilder()
var i = 0
for(i <- 0 until s.length())
{
var c = s.charAt(i)
if(Character.isDigit(c))
sb.append(c)
if(i + 1 < s.length())
{
var d = s.charAt(i + 1)
if(Character.isDigit(d) == false && sb.length() > 0)
{
e.append(new NumberElement(sb.toString()))
sb.clear()
}
}
if(c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '(' || c == ')')
e.append(new OperatorElement(c));
}
if(sb.length() > 0)
e.append(new NumberElement(sb.toString()));
return e
}
}
InfixToPostfix.scala
package calculator
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Stack
import util.control.Breaks._
class InfixToPostfix {
private var converted: ArrayBuffer[Element] = new ArrayBuffer[Element]
def Precedence(c: OperatorElement) : Int =
{
if(c.type1 == EXPONENTIAL)
{
return 2
}
else if(c.type1 == MULTIPLY || c.type1 == DIVIDE)
{
return 3
}
else if(c.type1 == ADD || c.type1 == SUBTRACT)
{
return 4
}
else
return Int.MaxValue
}
def ProcessOperators(st: Stack[Element], element: Element, top: Element)
{
var top1 = top;
breakable
{
while(st.size > 0 && Precedence(element.asInstanceOf[OperatorElement]) >= Precedence(top1.asInstanceOf[OperatorElement]))
{
var p = st.pop()
if(p.asInstanceOf[OperatorElement].type1 == OPAREN)
break
converted.append(p)
if(st.size > 0)
top1 = st.top
}
}
}
def ConvertFromInfixToPostFix(e: ArrayBuffer[Element]) : ArrayBuffer[Element] =
{
var stack1: ArrayBuffer[Element] = new ArrayBuffer[Element]()
e.copyToBuffer(stack1)
var st: Stack[Element] = new Stack[Element]()
var i: Int = 0
for(i <- 0 until stack1.length)
{
var element = stack1(i)
if(element.isInstanceOf[OperatorElement])
{
if(st.isEmpty || element.asInstanceOf[OperatorElement].type1 == OPAREN)
st.push(element);
else
{
var top = st.top;
if(element.asInstanceOf[OperatorElement].type1 == CPAREN)
ProcessOperators(st, element, top);
else if(Precedence(element.asInstanceOf[OperatorElement]) < Precedence(top.asInstanceOf[OperatorElement]))
st.push(element);
else
{
ProcessOperators(st, element, top);
st.push(element);
}
}
}
else
converted.append(element);
}
while(st.size > 0)
{
var b1 = st.pop()
converted.append(b1)
}
return converted
}
override def toString(): String =
{
var sb: StringBuffer = new StringBuffer()
converted.foreach(f => sb.append(f + " "))
return sb.toString()
}
}
PostFixEvaluator.scala
package calculator
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Stack
class PostFixEvaluator {
def calculate(left: NumberElement, right: NumberElement, op: OperatorElement): NumberElement =
{
var temp = Double.MaxValue
if(op.type1 == ADD)
{
temp = left.getNumber + right.getNumber
}
else if(op.type1 == SUBTRACT)
{
temp = left.getNumber - right.getNumber
}
else if(op.type1 == MULTIPLY)
{
temp = left.getNumber * right.getNumber
}
else if(op.type1 == DIVIDE)
{
temp = left.getNumber / right.getNumber
}
else if(op.type1 == EXPONENTIAL)
{
temp = Math.pow(left.getNumber, right.getNumber)
}
return new NumberElement(temp.toString)
}
def Evaluate(e: ArrayBuffer[Element]): Double =
{
var stack: Stack[Element] = new Stack[Element]
var v: ArrayBuffer[Element] = new ArrayBuffer[Element]
e.copyToBuffer(v)
var i: Int = 0
for(i <- 0 until v.length)
{
var element = v(i)
if(element.isInstanceOf[NumberElement])
stack.push(element)
if(element.isInstanceOf[OperatorElement])
{
var right = stack.pop()
var left = stack.pop()
var result = calculate(left.asInstanceOf[NumberElement], right.asInstanceOf[NumberElement], element.asInstanceOf[OperatorElement])
stack.push(result)
}
}
return stack.pop().asInstanceOf[NumberElement].getNumber
}
}
Calculator.scala
package calculator
object Calculator {
def main(args: Array[String]): Unit = {
val t = "4+6+9*8-(5*6+9)^2"
val p = new Parser()
var e = p.Parse(t)
var i = new InfixToPostfix()
e = i.ConvertFromInfixToPostFix(e)
println(i)
var pfe = new PostFixEvaluator();
var result = pfe.Evaluate(e);
println(result)
}
}