-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTCalc.cpp
More file actions
214 lines (194 loc) · 4.72 KB
/
TCalc.cpp
File metadata and controls
214 lines (194 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#include "TCalc.h"
#include <iostream>
#include "TStack.h"
int TCalc::GetPriority(char op)
{
if (op == '+' || op == '-')
{
return 1;
}
if (op == '*' || op == '/')
{
return 2;
}
if (op == '^')
{
return 3;
}
return 0;
}
double TCalc::CalcPostfix()
{
StNum.clear();
string number = "";
for (int i = 0; i < postfix.size(); i++)
{
char sim = postfix[i];
if (isdigit(sim) || sim == '.')
{
number += sim; // ñîáèðàåì ÷èñëî
}
else if (sim == ' ' && !number.empty())
{
double num = stod(number);
StNum.push(num);
//cout << "Äîáàâëåíî ÷èñëî â ñòåê: " << num << endl; // Äëÿ îòëàäêè
number = "";
}
else if (sim == '+' || sim == '-' || sim == '*' || sim == '/' || sim == '^' || sim == '~')
{
if (StNum.getNum() < 1)
{
throw - 1;
}
double secondNum = StNum.pop();
double firstNum = StNum.pop();
double result = PerformOperation(firstNum, secondNum, postfix[i]);
StNum.push(result);
}
}
if (!number.empty()) {
double val = stod(number);
StNum.push(val);
}
if (StNum.getNum() != 0)
{
throw "Îøèáêà: íåâåðíîå êîëè÷åñòâî îïåðàíäîâ â âûðàæåíèè";
}
double result = StNum.pop();
return result;
}
void TCalc::ToPostfix()
{
postfix = "";
StChar.clear();
string number = "";
for (int i = 0; i < infix.size(); i++)
{
char sim = infix[i];
if (isdigit(sim) || sim == '.')
{
number += sim; // ñîáèðàåì ÷èñëî (âêëþ÷àÿ äåñÿòè÷íóþ òî÷êó)
if (i == infix.size() - 1 || (!isdigit(infix[i + 1]) && infix[i + 1] != '.')) // ïðîâåðêà, ÷òî ïîñëå ÷èñëà èäåò ïðîáåë èëè ñèìâîë îïåðàöèè
{
postfix += number + " ";
number = "";
}
}
else if (sim == '(')
{
StChar.push(sim);
}
else if (sim == ')')
{
while (!StChar.empty() && StChar.top() != '(')
{
postfix += StChar.pop();
postfix += " ";
}
StChar.pop();
}
else if (sim == '+' || sim == '-' || sim == '*' || sim == '/' || sim == '^')
{
while (!StChar.empty() && GetPriority(StChar.top()) >= GetPriority(sim))
{
postfix += StChar.pop();
postfix += " ";
}
StChar.push(sim);
}
}
while (!StChar.empty()) // ïåðåìåùàåì îñòàâøèåñÿ îïåðàòîðû èç ñòåêà â ïîñòôèêñíîå âûðàæåíèå
{
postfix += StChar.pop();
postfix += " ";
}
}
double TCalc::Calc()
{
string str = "(" + infix + ")";
StNum.clear();
StChar.clear();
if (!StChar.checkThrow(infix)) // ïðîâåðÿåì êîððåêòíîñòü ñêîáîê íà ïàðíîñòü
{
throw "îøèáêà: íåêîððåêòíîå âûðàæåíèå (íåïàðíûå ñêîáêè)!";
}
for (int i = 0; i < str.size(); ++i)
{
char tmp = str[i];
if (tmp == '(')
{
StChar.push(tmp); // ïîìåùàåì â ñòåê îïåðàòîðîâ
}
else if (tmp == '-')
{
if (i == 0 || str[i - 1] == '(') // ïðîâåðêà íà óíàðíûé ìèíóñ
{
str[i] = '_'; // îáîçíà÷àåì óíàðíûé ìèíóñ êàê îòäåëüíûé ñèìâîë
}
else // ýòî áèíàðíûé ìèíóñ
{
while (!StChar.empty() && GetPriority(StChar.top()) >= GetPriority(tmp)) // âûïîëíÿåì âñå îïåðàöèè èç ñòåêà >= ïî ïðèîðèòåòó
{
char op = StChar.pop();
double secondNum = StNum.pop();
double firstNum = StNum.pop();
StNum.push(PerformOperation(firstNum, secondNum, op));
}
StChar.push(tmp); // êëàäåì ìèíóñ â ñòåê îïåðàòîðîâ
}
}
else if (isdigit(tmp) || tmp == '.') // öèôðà èëè òî÷êà
{
size_t idx;
double num = stod(str.substr(i), &idx); // ïðåîáðàçîâàíèå ñòðîêè â ÷èñëî
StNum.push(num); // êëàäåì â ñòåê ÷èñåë
i += idx - 1;
}
else if (tmp == ')')
{
while (!StChar.empty() && StChar.top() != '(') // âû÷èñëÿåì âñå îïåðàöèè â òåêóùèõ ñêîáêàõ
{
char op = StChar.pop();
double num2 = StNum.pop();
double num1 = StNum.pop();
StNum.push(PerformOperation(num1, num2, op));
}
StChar.pop(); // óáèðàåì îòêðûâàþùóþ ñêîáêó
}
else if (tmp == '+' || tmp == '*' || tmp == '/' || tmp == '^')
{ // âûïîëíÿåì âñå îïåðàöèè ñ ïðèîðèòåòîì >= òåêóùåé
while (!StChar.empty() && GetPriority(StChar.top()) >= GetPriority(tmp)) {
char op = StChar.pop();
double num2 = StNum.pop();
double num1 = StNum.pop();
StNum.push(PerformOperation(num1, num2, op));
}
StChar.push(tmp);
}
else if (tmp == '_') // ïðåîáðàçóåì â îòðèöàòåëüíîå ÷èñëî
{
size_t idx;
double num = stod(str.substr(i + 1), &idx);
//double num = atof(&str[i + 1]); // *** - ïðèìåð ðàáîòû - âíèçó êîäà
//StNum.push(-num);
i += idx;
}
}
if (StNum.getNum() != 0) {
throw "Îøèáêà: íåâåðíîå êîëè÷åñòâî îïåðàíäîâ â âûðàæåíèè!";
}
return StNum.pop();
}
double TCalc::PerformOperation(double num1, double num2, char op) {
switch (op) {
case '+': return num1 + num2;
case '-': return num1 - num2;
case '*': return num1 * num2;
case '/':
if (num2 == 0) throw "Îøèáêà: äåëåíèå íà íîëü!";
return num1 / num2;
case '^': return pow(num1, num2);
default: throw "Îøèáêà: íåèçâåñòíàÿ îïåðàöèÿ!";
}
}