// Return a string output in RPN public string getRPN() { string[] splitExpr = expr.Split(' '); Stack<string> valsStk = new Stack<string>(); Stack<char> symbolStk = new Stack<char>(); return parse(splitExpr, valsStk, symbolStk); }
public void EnsureICanManuallyStoreLastIn() { string input = "8 * -2"; Stack stack = new Stack(); stack.Update(input, null); var actual = stack.LastIn; Assert.AreEqual(input, actual); }
private String parse(string[] tokens, Stack<string> vStk, Stack<char> sStk) { for (int i = 0; i < tokens.Length; i++) { string token = tokens[i]; switch (token) { case "+": case "-": case "*": case "/": while (!sStk.isEmpty()) { if (!sStk.Peek().Equals("(")) if (precedence(sStk.Peek()) >= precedence(token[0])) { vStk.Push(sStk.Pop() + ""); } else break; } sStk.Push(token[0]); break; case "(": sStk.Push(token[0]); break; case ")": while (!sStk.isEmpty()) { if (sStk.Peek().Equals('(')) { sStk.Pop(); break; } vStk.Push(sStk.Pop() + ""); } break; default: vStk.Push(token); break; } } while (!sStk.isEmpty()) vStk.Push(sStk.Pop() + ""); String result = ""; while (!vStk.isEmpty()) result = vStk.Pop() + " " + result; return result.Trim(); }
private string[] ToPolish() { var output = new string[_parsed.Length]; int i = 0; var stack = new Stack<string>(); foreach (var str in _parsed) { if (str == null) break; double x; //почему-то дробные числа записанные через точку - не парсит //если писать через запятую - все в порядке if (double.TryParse(str, out x)) { output[i++] = str; } else { if (str == "(") { stack.Push(str); } else if (str == ")") { while (stack.Top() != "(") output[i++] = stack.Pop(); stack.Pop(); } else if (str == "*" || str == "/" || str == "+" || str == "-" || str == "^") { while (!stack.Empty() && GetPriority(str) <= GetPriority(stack.Top())) { output[i++] = stack.Pop(); } stack.Push(str); } } } while (!stack.Empty()) { output[i++] = stack.Pop(); } return output; }
public void convert() { Stack<char> stack = new Stack<char> (); for (int i = 0; i < infixString.Length; i++) { string tmp = ""; char c = infixString [i]; while ("0123456789.".IndexOf (c) >= 0) { tmp += c; c = infixString [++i]; } if (tmp != "") { postfixString += tmp + " "; i--; } else if ("+-/x".IndexOf(c) >= 0) { // stack is empty, push operator if (stack.Count == 0) { stack.Push (c); } else { // if top of stack has higher precedence char topStack = stack.Peek(); Debug.WriteLine ("Top of stack: " + topStack); while (hasPrecedence(topStack, c) && stack.Count > 0) { Debug.WriteLine ("Popping from stack because " + topStack + " has precedence over " + c); char popped = stack.Pop (); postfixString += popped + " "; if (stack.Count > 0) topStack = stack.Peek (); Debug.WriteLine ("Post-fix string: " + postfixString); } stack.Push (c); } } } foreach (char c in stack) { postfixString += c + " "; } }
public double Calculate(IList<OperationElement> operationElements) { var operationInOnpOrder = SortElementsInOnpOrder(operationElements); var operationNumbers = new Stack<double>(); foreach (var operationElement in operationInOnpOrder) { if (operationElement.Type == OperationElementType.Number) { operationNumbers.Push(double.Parse(operationElement.Value)); } else { var secondNumber = operationNumbers.Pop(); var firstNumber = operationNumbers.Pop(); operationNumbers.Push(SimpleCalculations.Calculate(operationElement.Value, firstNumber, secondNumber)); } } return operationNumbers.Pop(); }
public PostfixCalculator (string expr) { string[] exprSplit = expr.Split (default(string[]), StringSplitOptions.RemoveEmptyEntries); answer = "under construction"; Debug.WriteLine ("split expression: " + exprSplit); Stack<float> stack = new Stack<float> (); for (int i = 0; i < exprSplit.Length; i++) { string val = exprSplit [i]; if (val == "+" || val == "-" || val == "/" || val == "x") { float a = stack.Pop (); float b = stack.Pop (); switch (val) { case "+": stack.Push ((float) a + b); break; case "-": stack.Push ((float) b - a); break; case "/": if (a == 0.0) { answer = "NaN"; return; } stack.Push ((float) b / a); break; case "x": stack.Push ((float) a * b); break; } } else { stack.Push (float.Parse (val)); } } answer = stack.Pop ().ToString (); }
public string[] ConvertToPostfixNotation(string input) { List<string> operators = new List<string>(standart_operators); List<string> outputSeparated = new List<string>(); Stack<string> stack = new Stack<string>(); foreach (string c in Separate(input)) { if (operators.Contains(c)) { if (stack.Count > 0 && !c.Equals("(")) { if (c.Equals(")")) { string s = stack.Pop(); while (!s.Equals("(")) { outputSeparated.Add(s); s = stack.Pop(); } } else if (GetPriority(c) > GetPriority(stack.Peek())) stack.Push(c); else { while (stack.Count > 0 && GetPriority(c) <= GetPriority(stack.Peek())) outputSeparated.Add(stack.Pop()); stack.Push(c); } } else stack.Push(c); } else outputSeparated.Add(c); } if (stack.Count > 0) foreach (string c in stack) outputSeparated.Add(c); return outputSeparated.ToArray(); }
private static string toPostfix(string infix) { string expr = infix; Stack<char> stack = new Stack<char>(); string postfix = ""; foreach (char chr in expr.ToArray()) { if (chr == '(') { stack.Push(chr); } else if ("+-*/".IndexOf(chr) != -1) { while(stack.Count != 0 && priority(stack.Peek()) >= priority(chr)) { postfix = postfix + stack.Pop(); } stack.Push(chr); } else if (chr == ')') { while (stack.Peek() != '(') { postfix = postfix + stack.Pop(); } stack.Pop(); } else { postfix = postfix + chr; } } while (stack.Count != 0) { postfix = postfix + stack.Pop(); } return postfix; }
public decimal CalculateRPN(string rpn) { string[] rpntokens = rpn.Split(' '); Stack<decimal> stack = new Stack<decimal>(); decimal number = decimal.Zero; foreach (string token in rpntokens) { if (decimal.TryParse(token, out number)) stack.Push(number); else { switch (token) { case "+": stack.Push(stack.Pop() + stack.Pop()); break; case "-": number = stack.Pop(); stack.Push(stack.Pop() - number); break; case "*": stack.Push(stack.Pop() * stack.Pop()); break; case "/": number = stack.Pop(); stack.Push(stack.Pop() / number); break; default: throw new InvalidOperationException("Unexpected Operators: " + token); } } } return stack.Pop(); }
/// <summary> /// Evaluate expression with Dijkstra's Shunting Yard Algorithm /// </summary> /// <returns>result of calculations</returns> public double? Calculate() { if (_input == null) throw new ArgumentException(); Stack<Op> operatorStack = new Stack<Op>(); Queue<Op> outputQueue = new Queue<Op>(); // Let's split the input string into a token list List<String> tokenList = Regex.Split(_input, TokenSplitRegex).Select(t => t.Trim()).Where(t => !String.IsNullOrEmpty(t)).ToList(); for (int tokenNum = 0; tokenNum < tokenList.Count(); ++tokenNum) { double? tmpValue; String token = tokenList[tokenNum]; TokenType tokenType = GetTokenType(token, out tmpValue); // Handle this token and insert into the correct queue or stack switch (tokenType) { case TokenType.Value: if (tmpValue.HasValue) outputQueue.Enqueue(new Operand(tmpValue.Value)); else throw new ArgumentException("Unknown operand " + token); break; case TokenType.Operator: Operator newOperator = GetOperator(token, (tokenNum == 0 || tokenList[tokenNum - 1] == "(")); if (operatorStack.Count > 0) { Op topOperator = operatorStack.Peek(); if (topOperator is Operator) { if (newOperator.Precedence <= ((Operator)topOperator).Precedence) { outputQueue.Enqueue(operatorStack.Pop()); } } } operatorStack.Push(newOperator); break; case TokenType.LeftParenthesis: operatorStack.Push(new LeftParenthesis()); break; case TokenType.RightParenthesis: // Handle all operators in the stack (i.e. move them to the outputQueue) // until we find the LeftParenthesis while (!(operatorStack.Peek() is LeftParenthesis)) { outputQueue.Enqueue(operatorStack.Pop()); } operatorStack.Pop(); break; case TokenType.Function: if ((tokenList.Count >= tokenNum + 1) && (tokenList[tokenNum + 1] == "(")) { Function.FunctionTypes type = Function.GetFunctionType(token); if (type == Function.FunctionTypes.UNKNOWN) { throw new ArgumentException("Unknown function " + token); } operatorStack.Push(new Function(type)); } break; } // If we don't find any token between a value and parenthesis, automatically // add a multiply sign if (tokenType == TokenType.Value || tokenType == TokenType.RightParenthesis) { if (tokenNum < tokenList.Count() - 1) { String nextToken = tokenList[tokenNum + 1]; TokenType nextTokenType = GetTokenType(nextToken, out tmpValue); if (nextTokenType != TokenType.Operator && nextTokenType != TokenType.RightParenthesis) { tokenList.Insert(tokenNum + 1, "*"); } } } } // Move all operators into the outputqueue while (operatorStack.Count > 0) { Op operand = operatorStack.Pop(); if (operand is LeftParenthesis || operand is RightParenthesis) { throw new ArgumentException("Mismatched parentheses"); } outputQueue.Enqueue(operand); } // Now we have the expression in reverse polish notation and it's easy to calculate // Step through the outputQueue and calculate the result Stack<Operand> outputStack = new Stack<Operand>(); while (outputQueue.Count > 0) { Op currentOp = outputQueue.Dequeue(); if (currentOp is Operand) { outputStack.Push((Operand)currentOp); } else if (currentOp is Operator) { Operator currentOperator = (Operator)currentOp; currentOperator.Execute(outputStack, this.Mode); } } // If we haven't got only one answer, the formula is invalid, return that. if (outputStack.Count != 1) { throw new ArgumentException("Invalid formula"); } // Pop and return the result return outputStack.Pop().Value; }
public static Element Evaluate(string s, ref int i) { int start = i; Stack<Element> element = new Stack<Element>(); Stack<Operator> op = new Stack<Operator>(); op.Push(new OpenBracket()); for (; i < s.Length;) { char c = s[i]; if (c == ' ') { i++; continue; } if (StrNumber.IndexOf(c) != -1) { element.Push(getDouble(s, ref i)); continue; } if (StrOperator.IndexOf(c) != -1) { if(c == '-' && (i == 0 || (StrOperator + '(').IndexOf(s[i-1]) != -1)) { i++; Negative n = new Negative(); n.Inputs.Add(Evaluate(s, ref i)); element.Push(n); continue; } if (c == '+' && (i == 0 || (StrOperator + '(').IndexOf(s[i - 1]) != -1)) { i++; continue; } Operator temp = getOperator(s, ref i); while (temp.Level <= op.Peek().Level && !(temp is OpenBracket)) { Operator o = op.Pop(); o.MakeInput(element); element.Push(o); } op.Push(temp); continue; } if (c == '(') { i++; element.Push(Evaluate(s, ref i)); continue; } if (StrEnd.IndexOf(c) != -1) { while (!(op.Peek() is OpenBracket)) { Operator o = op.Pop(); o.MakeInput(element); element.Push(o); } op.Pop(); break; } element.Push(getSpec(s, ref i)); } if (element.Count != 1) throw new Exception("Error when calculate \"" + s.Substring(start, i - start) + "\""); return element.Pop(); }
public decimal result(string input) { Stack<string> stack = new Stack<string>(); Queue<string> queue = new Queue<string>(ConvertToPostfixNotation(input)); string str = queue.Dequeue(); while (queue.Count >= 0) { if (!operators.Contains(str)) { stack.Push(str); str = queue.Dequeue(); } else { decimal summ = 0; switch (str) { case "+": { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = a + b; break; } case "-": { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = b - a; break; } case "*": { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = b * a; break; } case "/": { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = b / a; break; } case "^": { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = Convert.ToDecimal(Math.Pow(Convert.ToDouble(b), Convert.ToDouble(a))); break; } } stack.Push(summ.ToString()); if (queue.Count > 0) str = queue.Dequeue(); else break; } } return Convert.ToDecimal(stack.Pop()); }
/// <summary> /// Method for check and extract two values from stack. /// </summary> /// <param name="st">stack</param> /// <returns>decimal array</returns> private static decimal[] ContainValFromStack(Stack<decimal> st) { decimal[] twoVal = new decimal[2]; if (st.Count != 0) { twoVal[0] = st.Pop(); } else { throw new ExpresionExceptions("Error! You input incorrect expression."); } if (st.Count != 0) { twoVal[1] = st.Pop(); } else { throw new ExpresionExceptions("Error! You input incorrect expression."); } return twoVal; }
/// <summary> /// Main method for calculate expression /// </summary> /// <param name="inputRPNExpression">RPN expression</param> /// <returns>decimal</returns> public static decimal Calculate(string inputRPNExpression) { string[] items = inputRPNExpression.Split(' '); Stack<decimal> stack = new Stack<decimal>(); decimal tmpNumber = decimal.Zero; decimal result = decimal.Zero; foreach (string token in items) { if (decimal.TryParse(token, NumberStyles.Any, new CultureInfo("en-US"), out tmpNumber)) { stack.Push(tmpNumber); } else if (Constants.SIMPLE_OPERATORS.IndexOf(token) != -1) { switch (token) { case "*": { decimal[] values = ContainValFromStack(stack); stack.Push(Mul(values[0], values[1])); break; } case "/": { decimal[] values = ContainValFromStack(stack); tmpNumber = values[0]; if (tmpNumber != 0 && tmpNumber != (decimal)0.0) { stack.Push(Div(values[1], tmpNumber)); } else { throw new ExpresionExceptions("Error! Division by zero."); } break; } case "+": { decimal[] values = ContainValFromStack(stack); stack.Push(Add(values[0], values[1])); break; } case "-": { decimal[] values = ContainValFromStack(stack); tmpNumber = values[0]; stack.Push(Sub(values[1], tmpNumber)); break; } default: throw new ExpresionExceptions("Calculate error!"); } } else { throw new ExpresionExceptions("Out of range!"); } } if (stack.Count != 0) { result = RoundResult(stack.Pop()); return result; } else { throw new ExpresionExceptions("Error! You input incorrect expression."); } }
private void Eval() { Stack<double> values = new Stack<double>(); PostfixValue value; while (_postfix.Count > 0) { value = _postfix.Dequeue(); if (value.IsNumeric()) { values.Push(value.Value()); } else { switch (value.Operator()) { case '+': values.AddInPlace(); break; case '-': values.SubtractInPlace(); break; case '/': values.DivideInPlace(); break; case '*': values.MultiplyInPlace(); break; case '^': values.PowInPlace(); break; } } } if (values.Count > 1) throw new ArgumentException("Too many values"); _postfix.Enqueue(new PostfixValue(values.Pop())); }
protected Operator(Priority priority, Associativity associativity, Stack<double> stack) : base(stack) { Priority = priority; Associativity = associativity; }
private static double Evaluate( List<IToken> postfixExpression ) { var stackOfValues = new Stack<double>(); foreach( var token in postfixExpression ) token.Evaluate( stackOfValues ); return stackOfValues.Pop(); }
public Log(Stack<double> stack) : base(Priority.Function, Associativity.Right, stack) { }
public void Evaluate( Stack<double> stackOfValues ) { var rhs = stackOfValues.Pop(); var lhs = stackOfValues.Pop(); var res = this.Operator( lhs, rhs ); stackOfValues.Push( res ); }
protected Function(Priority priority, Associativity associativity, Stack<double> stack) : base(priority, associativity, stack) { }
protected BinaryOperator(Priority priority, Associativity associativity, Stack<double> stack) : base(priority, associativity, stack) { }
protected Token(Stack<double> stack) { this.stack = stack; }
public Calc() { _postfix = new Queue<PostfixValue>(); _operators = new Stack<char>(); Operators = new Dictionary<char, int>() { { '-', 0 }, { '+', 0 }, { '/', 1 }, { '*', 1 }, { '^', 2 }, { '(', -1 }, { ')', -1 } }; }
public Number(double value, Stack<double> stack) : base(stack) { Value = value; }
public Expression(string expression) { variables = new Dictionary<string, Variable>(); workStack = new Stack<double>(); operatorStack = new Stack<Operator>(); tokens = new List<Token>(); CreateOperators(); createVariable("pi", Math.PI); createVariable("e", Math.E); createVariable("∞", double.PositiveInfinity); createVariable("NaN", double.NaN); createVariable("Epsilon", double.Epsilon); createVariable("MinValue", double.MinValue); createVariable("MaxValue", double.MaxValue); ExpressionString = expression; parse(); }
public void Evaluate( Stack<double> stackOfValues ) { stackOfValues.Push( this.Value ); }
public Variable(double val, Stack<double> stack) : base(stack) { Value = val; this.stack = stack; }
//This function parses a string of numbers and operations and treats it as a single level of order of operations (no nested parentheses) //-It essentially just performs the multiplication/divided operations on the first pass condensing the string as it goes, and on the second pass it does addition/subtraction private static String solveString(String equation) { Stack<double> total = new Stack<double>(); char[] symbol = { '+', '-', '*', '/' }; char[] plusOrMinus = { '+', '-' }; char[] timesOrDivide = { '*', '/' }; char[] charEquation = equation.ToCharArray(); for (int i = 0; i < charEquation.Length; i++) { if (equation.IndexOfAny(symbol, i, 1) > -1 && charEquation.GetValue(i + 1).Equals('-')) { charEquation.SetValue('!', i + 1); } } equation = ""; foreach (char i in charEquation) { equation += Convert.ToString(i); } equation = "0+" + equation + "+0"; int num1_Start = 0; int num1_End = 0; int num2_Start = 0; int num2_End = 0; String num1_str = ""; String num2_str = ""; String answer = ""; double num1 = 0; double num2 = 0; int pos = 0; //Position of last + or - operator before current * or / operator double numBuffer = 0; while (equation.IndexOfAny(timesOrDivide) > -1) { pos = LastIndexOfAny(equation, plusOrMinus, 0, equation.IndexOfAny(timesOrDivide)); num1_Start = pos + 1; num1_End = equation.IndexOfAny(timesOrDivide) - 1; num2_Start = equation.IndexOfAny(timesOrDivide) + 1; num2_End = equation.IndexOfAny(symbol, equation.IndexOfAny(timesOrDivide) + 1) - 1; num1_str = equation.Substring(num1_Start, num1_End - num1_Start + 1); num2_str = equation.Substring(num2_Start, num2_End - num2_Start + 1); if (num1_str.IndexOf("!") > -1) { num1_str = num1_str.Replace("!", "-"); } if (num2_str.IndexOf("!") > -1) { num2_str = num2_str.Replace("!", "-"); } num1 = Convert.ToDouble(num1_str); num2 = Convert.ToDouble(num2_str); if (equation.Substring(equation.IndexOfAny(timesOrDivide), 1) == "*") { answer = Convert.ToString(num1 * num2); } else { answer = Convert.ToString(num1 / num2); } if (answer.IndexOf("-") > -1) { answer = answer.Replace("-", "!"); } if (answer.IndexOf("-") > -1) { answer = answer.Replace("-", "!"); } equation = equation.Substring(0, num1_Start) + answer + equation.Substring(num2_End + 1, equation.Length - num2_End - 1); } equation = equation.Insert(0, "+"); while (equation.IndexOfAny(plusOrMinus) > -1) { if (equation.Substring(1, 1).Equals("!")) { if (equation.Substring(0, 1).Equals("+")) { total.Push(Convert.ToDouble("-" + equation.Substring(2, equation.IndexOfAny(plusOrMinus, 1) - 2))); equation = equation.Remove(0, equation.IndexOfAny(plusOrMinus, 1)); } else { total.Push(Convert.ToDouble(equation.Substring(2, equation.IndexOfAny(plusOrMinus, 2) - 2))); equation = equation.Remove(0, equation.IndexOfAny(plusOrMinus, 1)); } } else if (equation.Length > 2) { if (equation.Substring(0, 1).Equals("+")) { total.Push(Convert.ToDouble(equation.Substring(1, equation.IndexOfAny(plusOrMinus, 1) - 1))); equation = equation.Remove(0, equation.IndexOfAny(plusOrMinus, 1)); } else { total.Push(Convert.ToDouble("-" + equation.Substring(1, equation.IndexOfAny(plusOrMinus, 1) - 1))); equation = equation.Remove(0, equation.IndexOfAny(plusOrMinus, 1)); } } else { equation = ""; } } while (total.Count > 0) { numBuffer += total.Pop(); } return Convert.ToString(numBuffer); }
public Expression Parse(string statement) { if (string.IsNullOrEmpty(statement)) throw new ArgumentNullException(nameof(statement)); var position = 0; var operatorStack = new Stack<ArithmeticToken>(); var outputQueue = new Queue<ArithmeticToken>(); while (true) { var currentToken = ArithmeticToken.GetNextToken(statement, position); // position could be passed by ref, but for sake of single responsibility... if (currentToken.Kind == ArithmeticTokenKind.NotSupported) { throw new InvalidArithmeticTokenException(currentToken); } if (currentToken.Kind == ArithmeticTokenKind.End) break; // while we have to copy position every time position += currentToken.Value.Length; if (currentToken.Kind == ArithmeticTokenKind.Nope) continue; if (currentToken.Kind == ArithmeticTokenKind.Double || currentToken.Kind == ArithmeticTokenKind.Integer) { outputQueue.Enqueue(currentToken); continue; } if (currentToken.Kind == ArithmeticTokenKind.Operator) { // there is an operator at the top of the operator stack if (operatorStack.Count > 0) { var op = operatorStack.Peek(); // with greater than or equal to precedence // and the operator is left associative var topStackOperatorInfo = op.GetOperatorInfo(); var currentOperatorInfo = currentToken.GetOperatorInfo(); if (topStackOperatorInfo != null && topStackOperatorInfo.IsLeft && topStackOperatorInfo.Precedence >= currentOperatorInfo.Precedence) // pop operators from the operator stack, onto the output queue. outputQueue.Enqueue(operatorStack.Pop()); } // push the read operator onto the operator stack operatorStack.Push(currentToken); continue; } if (currentToken.Kind == ArithmeticTokenKind.Priority) { const string LeftBracket = "("; // if the token is a left bracket (i.e. "(") if (currentToken.Value == LeftBracket) { // push it onto the operator stack. operatorStack.Push(currentToken); continue; } // if the token is a right bracket (i.e. ")") // while the operator at the top of the operator stack is not a left bracket: while (true) { // if the stack runs out without finding a left bracket, then there are // mismatched parentheses if (operatorStack.Count == 0) { throw new InvalidArithmeticStatementException("parentheses mismatched"); } // pop operator var op = operatorStack.Pop(); if (op.Value == LeftBracket) { break; } outputQueue.Enqueue(op); } } } // pop the operator onto the output queue while (operatorStack.Count > 0) { var op = operatorStack.Pop(); // if the operator token on the top of the stack is a bracket, then if (op.Kind == ArithmeticTokenKind.Priority) { // there are mismatched parentheses throw new InvalidArithmeticStatementException("parentheses mismatched"); } outputQueue.Enqueue(op); } return ExpressionConverter.FromPostfixNotation(outputQueue); }
public void EnsureICanManuallyStoreLastOut() { string result = "-12"; Stack stack = new Stack(); stack.Update(null, result); var actual = stack.LastOut; Assert.AreEqual(result, actual); }