예제 #1
0
 // 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);
 }
예제 #2
0
 public void EnsureICanManuallyStoreLastIn()
 {
     string input = "8 * -2";
     Stack stack = new Stack();
     stack.Update(input, null);
     var actual = stack.LastIn;
     Assert.AreEqual(input, actual);
 }
예제 #3
0
        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();
        }
예제 #4
0
파일: Calculator.cs 프로젝트: junk2112/.NET
        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 + " ";
			}

		}
예제 #6
0
		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 ();

		}
예제 #8
0
파일: Form1.cs 프로젝트: Pochatkin/MyRep
        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();
        }
예제 #9
0
        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;
        }
예제 #10
0
        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();
        }
예제 #11
0
        /// <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;
        }
예제 #12
0
        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();
        }
예제 #13
0
        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());
        }
예제 #14
0
        /// <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;
        }
예제 #15
0
        /// <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.");
            }
        }
예제 #16
0
        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()));
        }
예제 #17
0
 protected Operator(Priority priority, Associativity associativity, Stack<double> stack) : base(stack)
 {
     Priority = priority;
     Associativity = associativity;
 }
예제 #18
0
        private static double Evaluate( List<IToken> postfixExpression )
        {
            var stackOfValues = new Stack<double>();
            foreach( var token in postfixExpression )
                token.Evaluate( stackOfValues );

            return stackOfValues.Pop();
        }
예제 #19
0
 public Log(Stack<double> stack) : base(Priority.Function, Associativity.Right, stack) { }
예제 #20
0
 public void Evaluate( Stack<double> stackOfValues )
 {
     var rhs = stackOfValues.Pop();
     var lhs = stackOfValues.Pop();
     var res = this.Operator( lhs, rhs );
     stackOfValues.Push( res );
 }
예제 #21
0
 protected Function(Priority priority, Associativity associativity, Stack<double> stack) : base(priority, associativity, stack) { }
예제 #22
0
 protected BinaryOperator(Priority priority, Associativity associativity, Stack<double> stack) : base(priority, associativity, stack) { }
예제 #23
0
 protected Token(Stack<double> stack)
 {
     this.stack = stack;
 }
예제 #24
0
 public Calc()
 {
     _postfix = new Queue<PostfixValue>();
       _operators = new Stack<char>();
       Operators = new Dictionary<char, int>() { { '-', 0 }, { '+', 0 }, { '/', 1 }, { '*', 1 }, { '^', 2 }, { '(', -1 }, { ')', -1 } };
 }
예제 #25
0
 public Number(double value, Stack<double> stack) : base(stack)
 {
     Value = value;
 }
예제 #26
0
 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();
 }
예제 #27
0
 public void Evaluate( Stack<double> stackOfValues )
 {
     stackOfValues.Push( this.Value );
 }
예제 #28
0
 public Variable(double val, Stack<double> stack) : base(stack)
 {
     Value = val;
     this.stack = stack;
 }
예제 #29
0
        //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);
        }
예제 #30
0
        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);
        }
예제 #31
-1
 public void EnsureICanManuallyStoreLastOut()
 {
     string result = "-12";
     Stack stack = new Stack();
     stack.Update(null, result);
     var actual = stack.LastOut;
     Assert.AreEqual(result, actual);
 }