Files
Evil_Calculator/Evil Calculator/ReversePolishNotationSolver.cs

100 lines
4.0 KiB
C#

namespace Lunar.Evil_Calculator
{
internal static class ReversePolishNotationSolver
{
private static List<Token> ToReversePolishNotation(List<Token> equation)
{
List<Token> reversedEquation = new List<Token>();
Stack<Token> operators = new Stack<Token>();
foreach (Token token in equation)
{
if (token.tokenType == Token.TokenType.Operand)
{
reversedEquation.Add(token);
}
if (token.tokenType == Token.TokenType.Operator)
{
if (token.value == "(")
{
operators.Push(token);
}
else if (token.value == ")")
{
while (operators.Peek().value != "(")
{
reversedEquation.Add(operators.Pop());
}
operators.Pop();
}
else
{
while (operators.Count != 0 && operators.Peek().priority >= token.priority)
{
reversedEquation.Add(operators.Pop());
}
operators.Push(token);
}
}
}
while (operators.Count != 0)
{
reversedEquation.Add(operators.Pop());
}
return reversedEquation;
}
public static string Solve(List<Token> originalEquation)
{
List<Token> reversedEquation = ToReversePolishNotation(originalEquation);
Stack<Token> stack = new Stack<Token>();
foreach (Token token in reversedEquation)
{
double result, left, right;
if (token.tokenType == Token.TokenType.Operand)
{
stack.Push(token);
}
if (token.tokenType == Token.TokenType.Operator)
{
switch (token.value)
{
case "+":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = left + right;
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
case "-":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = left - right;
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
case "*":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = left * right;
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
case "/":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = left / right;
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
case "^":
right = Convert.ToDouble(stack.Pop().value);
left = Convert.ToDouble(stack.Pop().value);
result = Math.Pow(left, right);
stack.Push(new Token(Token.TokenType.Operand, result.ToString()));
break;
}
}
}
return stack.Pop().value;
}
}
}