SHOW:
|
|
- or go back to the newest paste.
| 1 | using System; | |
| 2 | using System.Collections.Generic; | |
| 3 | using System.Linq; | |
| 4 | using System.Text; | |
| 5 | ||
| 6 | namespace TEST_ExpressionParser | |
| 7 | {
| |
| 8 | static class ExpressionEvaluator | |
| 9 | {
| |
| 10 | private static int Priority(char op) | |
| 11 | {
| |
| 12 | if (op == '+' || op == '-') return 1; | |
| 13 | if (op == '*' || op == '/' || op == '%') return 2; | |
| 14 | if (op == '^') return 3; | |
| 15 | ||
| 16 | return 0; | |
| 17 | } | |
| 18 | ||
| 19 | private static bool IsOperand(char c) | |
| 20 | {
| |
| 21 | if (!char.IsLetterOrDigit(c)) return false; | |
| 22 | return true; | |
| 23 | } | |
| 24 | ||
| 25 | private static bool IsOperator(char c) | |
| 26 | {
| |
| 27 | return (c == '+' || c == '-' || c == '*' || c == '/' || c == '%' || c == '^'); | |
| 28 | } | |
| 29 | ||
| 30 | private static string GetOperand(string text, ref int start) | |
| 31 | {
| |
| 32 | StringBuilder str = new StringBuilder(); | |
| 33 | ||
| 34 | while (start < text.Length && (char.IsLetterOrDigit(text[start]) || text[start] == '.')) | |
| 35 | {
| |
| 36 | str.Append(text[start]); | |
| 37 | start++; | |
| 38 | } | |
| 39 | ||
| 40 | start--; | |
| 41 | return str.ToString(); | |
| 42 | } | |
| 43 | ||
| 44 | public static string ConvertToPostfix(string input) | |
| 45 | {
| |
| 46 | Stack<char> stack = new Stack<char>(); | |
| 47 | StringBuilder str = new StringBuilder(); | |
| 48 | ||
| 49 | // To avoid confusion, replace negative numbers with 0 - number | |
| 50 | if (input[0] == '-') input = input.Insert(0, "0"); | |
| 51 | while (input.Contains("( ")) input = input.Replace("( ", "(");
| |
| 52 | input = input.Replace("(-", "(0-");
| |
| 53 | ||
| 54 | for (int i = 0; i < input.Length; i++) | |
| 55 | {
| |
| 56 | if (char.IsWhiteSpace(input[i])) continue; | |
| 57 | ||
| 58 | if (IsOperand(input[i])) | |
| 59 | {
| |
| 60 | str.Append(GetOperand(input, ref i)); | |
| 61 | str.Append(' ');
| |
| 62 | } | |
| 63 | ||
| 64 | else if (input[i] == '(') stack.Push('(');
| |
| 65 | ||
| 66 | else if (input[i] == ')') | |
| 67 | {
| |
| 68 | while (stack.Peek() != '(')
| |
| 69 | {
| |
| 70 | str.Append(stack.Pop()); | |
| 71 | str.Append(' ');
| |
| 72 | } | |
| 73 | stack.Pop(); | |
| 74 | } | |
| 75 | ||
| 76 | else if (IsOperator(input[i])) | |
| 77 | {
| |
| 78 | if (stack.Count == 0) stack.Push(input[i]); | |
| 79 | ||
| 80 | else | |
| 81 | {
| |
| 82 | while (stack.Count != 0 && Priority(input[i]) <= Priority(stack.Peek())) | |
| 83 | {
| |
| 84 | str.Append(stack.Pop()); | |
| 85 | str.Append(' ');
| |
| 86 | } | |
| 87 | ||
| 88 | stack.Push(input[i]); | |
| 89 | } | |
| 90 | } | |
| 91 | } | |
| 92 | ||
| 93 | while (stack.Count > 0) | |
| 94 | {
| |
| 95 | str.Append(stack.Pop()); | |
| 96 | str.Append(' ');
| |
| 97 | } | |
| 98 | ||
| 99 | return str.ToString(); | |
| 100 | } | |
| 101 | ||
| 102 | private static double EvalSmall (double a, double b, char op) | |
| 103 | {
| |
| 104 | switch (op) | |
| 105 | {
| |
| 106 | case '+': return a + b; | |
| 107 | case '-': return a - b; | |
| 108 | case '*': return a * b; | |
| 109 | case '/': return a / b; | |
| 110 | case '%': return a % b; | |
| 111 | case '^': return Math.Pow(a, b); | |
| 112 | } | |
| 113 | ||
| 114 | return 0; | |
| 115 | } | |
| 116 | ||
| 117 | public static double ParsePostfix(string text) | |
| 118 | {
| |
| 119 | Stack<double> stack = new Stack<double>(); | |
| 120 | ||
| 121 | for (int i = 0; i < text.Length; i++) | |
| 122 | {
| |
| 123 | if (char.IsWhiteSpace(text[i])) continue; | |
| 124 | ||
| 125 | if (IsOperand(text[i])) stack.Push(double.Parse(GetOperand(text, ref i))); | |
| 126 | ||
| 127 | else if (IsOperator(text[i])) {
| |
| 128 | double a = stack.Pop(); | |
| 129 | double b = stack.Pop(); | |
| 130 | stack.Push(EvalSmall(b, a, text[i])); | |
| 131 | } | |
| 132 | } | |
| 133 | ||
| 134 | return stack.Peek(); | |
| 135 | } | |
| 136 | } | |
| 137 | } |