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(); }
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 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 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 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(); }
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 Evaluate( Stack<double> stackOfValues ) { stackOfValues.Push( this.Value ); }
public void Evaluate( Stack<double> stackOfValues ) { var rhs = stackOfValues.Pop(); var lhs = stackOfValues.Pop(); var res = this.Operator( lhs, rhs ); stackOfValues.Push( res ); }
/// <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> /// 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())); }
private double GetResult() { var stack = new Stack<string>(); //обрабатываем массив foreach (var str in _polishNotation) { if (str == null) break; if (GetPriority(str) == -1) stack.Push(str); else if (str == "*" || str == "/" || str == "+" || str == "-" || str == "^") { double first = 0, second = 0; double.TryParse(stack.Pop(), out second); double.TryParse(stack.Pop(), out first); switch (str) { case "+": stack.Push((first + second).ToString(CultureInfo.InvariantCulture)); break; case "-": stack.Push((first - second).ToString(CultureInfo.InvariantCulture)); break; case "*": stack.Push((first * second).ToString(CultureInfo.InvariantCulture)); break; case "/": stack.Push((first / second).ToString(CultureInfo.InvariantCulture)); break; case "^": stack.Push(Math.Pow(first, second).ToString(CultureInfo.InvariantCulture)); break; } } //Console.WriteLine(stack.top()); } double result; if ((stack.GetSize() != 1) || !double.TryParse(stack.Top(), out result)) { //Console.WriteLine("Incorrect Input"); throw new IndexOutOfRangeException(); } return result; }
private static string ConvertExpressionToRPN(string inputExpression) { string output = string.Empty; Stack<string> operatorStack = new Stack<string>(); int countChars; int legthInputExpression = inputExpression.Length; for (countChars = 0; countChars < legthInputExpression; countChars++) { // Parse number in input expression if (Char.IsDigit(inputExpression[countChars]) || inputExpression[countChars] == '.') { while(!IsSimpleOperator(inputExpression[countChars])) { output += inputExpression[countChars]; countChars++; if (countChars == legthInputExpression) { break; } } output += " "; countChars--; } if (IsSimpleOperator(inputExpression[countChars])) { if (inputExpression[countChars] == '(') { operatorStack.Push(inputExpression[countChars].ToString()); } if (inputExpression[countChars] == ')') { string itemsAtBracket = operatorStack.Pop(); // items from stack to output string while (itemsAtBracket != "(") { output += itemsAtBracket + " "; itemsAtBracket = operatorStack.Pop(); } } if (inputExpression[countChars] != '(' && inputExpression[countChars] != ')') { // Adding operator to stack if not open|close quote if (operatorStack.Count() > 0 && GetPriorytyForItem(inputExpression[countChars].ToString()) <= GetPriorytyForItem(operatorStack.Peek())) { output += operatorStack.Pop() + " "; } operatorStack.Push(inputExpression[countChars].ToString()); } } } // Output items From stack to output string while (operatorStack.Count > 0) { output += operatorStack.Pop() + " "; } return output.Trim(); }
public String EquateTokens(double varX) { if (errorString != "") { return errorString; } Stack<Token> outputStack = new Stack<Token>(); foreach (Token token in outputQueue) { if (token.type == Token.TokenType.Variable) { if (varX != double.NaN && token.type == Token.TokenType.Variable) { token.value = varX; } else if (varX == double.NaN && token.type == Token.TokenType.Variable) { return "Error"; } outputStack.Push(token); } } foreach (Token token in outputQueue) { if (token.type == Token.TokenType.Number) { outputStack.Push(token); } else if (token.type == Token.TokenType.Operator) { double tokenAnswer = 0; Token tok1 = outputStack.Pop(); Token tok2 = null; if (token.parameterCount == 1 && token.assoc == Token.Associativity.Left) { if (outputStack.Count == 0) { return "Error"; } else { Token temp = outputStack.Pop(); outputStack.Push(tok1); tok1 = temp; } } else if (token.parameterCount == 2) { if (outputStack.Count == 0) { return "Error"; } else { tok2 = outputStack.Pop(); } } double value = 0; switch (token.operand) { case "+": tokenAnswer = tok2.value + tok1.value; break; case "-": tokenAnswer = tok2.value - tok1.value; break; case "*": tokenAnswer = tok2.value * tok1.value; break; case "÷": tokenAnswer = tok2.value / tok1.value; break; case "%": tokenAnswer = tok2.value % tok1.value; break; case "√": tokenAnswer = Math.Sqrt(tok1.value); break; case "Sin": value = equationHandler.isDegrees ? Math.PI * tok1.value / 180 : tok1.value; tokenAnswer = Math.Sin(value); break; case "Cos": value = equationHandler.isDegrees ? Math.PI * tok1.value / 180 : tok1.value; tokenAnswer = Math.Cos(value); break; case "Tan": value = equationHandler.isDegrees ? Math.PI * tok1.value / 180 : tok1.value; tokenAnswer = Math.Tan(value); break; } outputStack.Push(new Token(tokenAnswer)); } } if (outputStack.Count > 1) { return "Error"; } String outputString = ""; foreach (Token token in outputStack) { outputString += " " + token.GetString(); } return outputString; }
void MakeResult(ref List<CALCULATOR_TOKEN> listPostfix, ref string strResult) { //후위 표기식을 계산한다. 숫자면 스택에 넣고, 오퍼레이터면 스택에서 2개를 꺼내서 계산한다. Stack<int> stackTemp = new Stack<int>(); foreach (CALCULATOR_TOKEN trace in listPostfix) { if (trace.nPrecedence == (int)PRECEDENCE.OPERAND) { stackTemp.Push(Int32.Parse(trace.strValue)); } else { switch (trace.strValue) { case "+": { int op1 =stackTemp.Pop(); int op2 = stackTemp.Pop(); stackTemp.Push(op1 + op2); }break; case "-": { int op1 = stackTemp.Pop(); int op2 = stackTemp.Pop(); stackTemp.Push(op2 - op1); } break; case "*": { int op1 = stackTemp.Pop(); int op2 = stackTemp.Pop(); stackTemp.Push(op1 * op2); } break; case "/": { int op1 = stackTemp.Pop(); int op2 = stackTemp.Pop(); stackTemp.Push(op1 / op2); } break; } } } //결과를 뿌려준다. strResult = stackTemp.Pop().ToString(); }
void MakePostFix(ref List<CALCULATOR_TOKEN> listToken, ref List<CALCULATOR_TOKEN> listPostFix) { //후위 표기식으로 변환한다. Stack<CALCULATOR_TOKEN> stackTemp = new Stack<CALCULATOR_TOKEN>(); foreach (CALCULATOR_TOKEN token in listToken) { if (token.nPrecedence == (int)PRECEDENCE.OPERAND) { listPostFix.Add(token); } else { while(stackTemp.Count != 0) { CALCULATOR_TOKEN tempToken = stackTemp.Pop(); if ((int)token.nPrecedence < (int)tempToken.nPrecedence) { listPostFix.Add(tempToken); } else { //우선순위가 낮은것을 만나면, tempToken을 다시 스택에 넣어주고, 자기자신도 넣는다. stackTemp.Push(tempToken); stackTemp.Push(token); break; } } //stackTemp에는 오퍼레이터만 들어가 있으니까 스택이 비면 자기를 넣어 준다. if (stackTemp.Count == 0) { stackTemp.Push(token); } } } //이제 오퍼레이터들을 넣어 준다. foreach (CALCULATOR_TOKEN token in stackTemp) { listPostFix.Add(token); } // 후위 표기식 완료 한번 뿌려보자 Debug.WriteLine("후위 표기식 변환 확인"); foreach (CALCULATOR_TOKEN trace in listPostFix) { Debug.WriteLine("value : " + trace.strValue + " precedencd : " + trace.nPrecedence); } }
public decimal result(string input) { input = correction(input); input = toUnarMinus(input); List<string> operators = new List<string>(standart_operators); 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)) { try { stack.Push(str); str = queue.Dequeue(); } catch { stack.Clear(); stack.Push("Unparsable"); break; } } else { decimal summ = 0; switch (str) { case "+": { try { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = a + b; break; } catch { return Convert.ToDecimal("asdasd"); break; } } case "-": { try { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = b - a; break; } catch { return Convert.ToDecimal("asdasd"); break; } } case "*": { try { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = a * b; break; } catch { return Convert.ToDecimal("asdasd"); break; } } case "/": { try { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = b / a; break; } catch { return Convert.ToDecimal("asdasd"); break; } } case "^": { try { decimal a = Convert.ToDecimal(stack.Pop()); decimal b = Convert.ToDecimal(stack.Pop()); summ = Convert.ToDecimal(Math.Pow(Convert.ToDouble(b), Convert.ToDouble(a))); break; } catch { return Convert.ToDecimal("asdasd"); break; } } case "@": { try { decimal a = Convert.ToDecimal(stack.Pop()); summ = -a; break; } catch { break; } } } stack.Push(summ.ToString()); if (queue.Count > 0) str = queue.Dequeue(); else break; } } if (stack.ToArray().Length > 1) { string s = "sasdasd"; decimal b = Convert.ToDecimal(s); return b; } else { return Convert.ToDecimal(stack.Pop()); } }
//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); }