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 | } |