public static List <Value> ReversePolishNotashion(string input) { Stack <OperatorValue> stack = new Stack <OperatorValue>(); List <Value> output = new List <Value>(); int countInt = 0; for (int i = 0; i < input.Length; i++) { if (OperatorValue.IsOperator(input[i])) { AddOperatorToStack(stack, output, new OperatorValue(input[i])); countInt = 0; } else if (Char.IsNumber(input[i]) && countInt == 0) { int value = Convert.ToInt32(input[i].ToString()); output.Add(new NumericValue(value)); countInt++; } else if (Char.IsNumber(input[i]) && countInt != 0) { var number = output.Last(); int j = output.Count() - 1; int value = Convert.ToInt32(number.ToString()) * 10 + Convert.ToInt32(input[i].ToString()); output[j] = new NumericValue(value); countInt++; } else if (input[i].ToString() == "(") { stack.Push(new OperatorValue(input[i])); } else if (input[i].ToString() == ")") { while (stack.Peek().ToString() != "(") { output.Add(stack.Pop()); } stack.Pop(); } //if (Char.IsNumber(input[i])) //{ // int value = Convert.ToInt32(input[i].ToString()); // output.Add(new NumericValue(value)); //} /*Если символ является открывающей скобкой, помещаем его в стек. * Если символ является закрывающей скобкой: * До тех пор, пока верхним элементом стека не станет открывающая скобка, выталкиваем элементы из стека в выходную строку. * При этом открывающая скобка удаляется из стека, но в выходную строку не добавляется. Если после этого шага на вершине стека оказывается символ функции, выталкиваем его в выходную строку. * Если стек закончился раньше, чем мы встретили открывающую скобку, это означает, что в выражении либо неверно поставлен разделитель, либо не согласованы скобки.*/ } PushRemainingOperatorsToOutput(stack, output); return(output); }
private static void AddOperatorToStack(Stack <OperatorValue> stack, List <Value> output, OperatorValue operatorValue) { /* * 1) пока… * … (если оператор o1 ассоциированный, либо лево-ассоциированный) приоритет o1 меньше либо равен приоритету оператора, находящегося на вершине стека… * … (если оператор o1 право-ассоциированый) приоритет o1 меньше приоритета оператора, находящегося на вершине стека… ---- * … выталкиваем верхние элементы стека в выходную строку; * 2) помещаем оператор o1 в стек. */ if (stack.Count > 0) { var topOperator = stack.Peek(); while (stack.Count > 0 && operatorValue.Priority <= topOperator.Priority) { output.Add(stack.Pop()); //topOperator = stack.Peek(); } } stack.Push(operatorValue); }
private static void AddOperatorToStack(Stack<OperatorValue> stack, List<Value> output, OperatorValue operatorValue) { /* * 1) пока… … (если оператор o1 ассоциированный, либо лево-ассоциированный) приоритет o1 меньше либо равен приоритету оператора, находящегося на вершине стека… … (если оператор o1 право-ассоциированый) приоритет o1 меньше приоритета оператора, находящегося на вершине стека… ---- … выталкиваем верхние элементы стека в выходную строку; 2) помещаем оператор o1 в стек. */ if (stack.Count>0) { var topOperator = stack.Peek(); while (stack.Count > 0 && operatorValue.Priority <= topOperator.Priority) { output.Add(stack.Pop()); //topOperator = stack.Peek(); } } stack.Push(operatorValue); }