117 lines
4.3 KiB
C#
117 lines
4.3 KiB
C#
namespace Lunar.Evil_Calculator
|
|
{
|
|
internal class ReverseNotationSolver
|
|
{
|
|
List<Token> equation = new List<Token>();
|
|
|
|
public string? ToReverseNotation(ref List<Token> equation)
|
|
{
|
|
List<Token> TEMP = new List<Token>();
|
|
Stack<Token> OPERATORS = new Stack<Token>();
|
|
foreach (Token token in equation)
|
|
{
|
|
if (token.tokenType == Token.TokenType.Operand)
|
|
{
|
|
TEMP.Add(token);
|
|
}
|
|
if (token.tokenType == Token.TokenType.Operator)
|
|
{
|
|
if (token.value == "(")
|
|
{
|
|
OPERATORS.Push(token);
|
|
}
|
|
else if (token.value == ")")
|
|
{
|
|
while (OPERATORS.Peek().value != "(")
|
|
{
|
|
TEMP.Add(OPERATORS.Pop());
|
|
}
|
|
OPERATORS.Pop();
|
|
}
|
|
else
|
|
{
|
|
while (OPERATORS.Count != 0 ? OPERATORS.Peek().priority >= token.priority : false)
|
|
{
|
|
TEMP.Add(OPERATORS.Pop());
|
|
}
|
|
OPERATORS.Push(token);
|
|
}
|
|
}
|
|
}
|
|
while (OPERATORS.Count != 0)
|
|
{
|
|
TEMP.Add(OPERATORS.Pop());
|
|
}
|
|
this.equation = TEMP;
|
|
return equationToString();
|
|
}
|
|
|
|
|
|
|
|
public string? Solve(ref List<Token> equation)
|
|
{
|
|
ToReverseNotation(ref equation);
|
|
Stack<Token> stack = new Stack<Token>();
|
|
foreach (Token token in this.equation)
|
|
{
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
public string equationToString()
|
|
{
|
|
string equationString = "";
|
|
foreach (Token token in this.equation)
|
|
{
|
|
equationString += token.value.ToString() + " ";
|
|
}
|
|
return equationString;
|
|
}
|
|
|
|
|
|
}
|
|
}
|