forked from Lunya-sh/Evil_Calculator
100 lines
4.0 KiB
C#
100 lines
4.0 KiB
C#
namespace Lunar.Evil_Calculator
|
|
{
|
|
internal static class ReverseNotationSolver
|
|
{
|
|
private static List<Token> ToReverseNotation(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 = ToReverseNotation(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;
|
|
}
|
|
}
|
|
}
|