/// <summary> /// Performs the shunting-yard algorithm on an input to convert from infix to postfix notation /// </summary> /// <param name="input">String input in infix notation</param> /// <returns>Queue of elements in postfix notation</returns> public static Queue <Element> SYA(string input) { List <string> tokens = ParseInput(input).ToList(); Stack <Operator> opStack = new(); Queue <Element> outQueue = new(); foreach (string token in tokens) { //if the token is a number, simply add to queue if (double.TryParse(token, out double number)) { outQueue.Enqueue(new Value(number)); } //if the token is an operator else if (OperatorsHelper.TryParse(token, out Operators op) && op != Operators.LeftBracket && op != Operators.RightBracket) { //move operators from operator stack to output queue while the top element in operator stack has greater precedence while (opStack.Count > 0 && opStack.Peek().Precedence() > op.Precedence()) { outQueue.Enqueue(opStack.Pop()); } //once all operators of greater precedence gone, add operator to operator queue opStack.Push(new Operator(op)); } //if the operator is a left bracket, just push onto opstack else if (op == Operators.LeftBracket) { opStack.Push(new Operator(op)); } //if right bracket, move operators from opstack to outqueue until left bracket is found //then discard both left and right bracket else if (op == Operators.RightBracket) { while (opStack.Peek().Op != Operators.LeftBracket) { outQueue.Enqueue(opStack.Pop()); } opStack.Pop(); } //otherwise, assume it's a variable else { outQueue.Enqueue(new Variable(token)); } } //once all tokens are done, move all operators over to output queue while (opStack.Count > 0) { outQueue.Enqueue(opStack.Pop()); } return(outQueue); }
public void ComputeTests(double expected, string input, double xValue = 0) { Queue <Element> elements = new(); foreach (string token in input.Split(' ')) { if (double.TryParse(token, out double number)) { elements.Enqueue(new Value(number)); } else if (OperatorsHelper.TryParse(token, out Operators op)) { elements.Enqueue(new Operator(op)); } else { elements.Enqueue(new Variable(token)); } } double value = RPN.Compute(elements, ("x", xValue)); Assert.AreEqual(expected, value, 1e-6); }
public void TryParseTests(Operators expected, string input) { Assert.IsTrue(OperatorsHelper.TryParse(input, out var op)); Assert.AreEqual(expected, op); }