-
Notifications
You must be signed in to change notification settings - Fork 0
/
Expression.cpp
137 lines (122 loc) · 4.39 KB
/
Expression.cpp
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
#include"Expression.h"
Expression::Expression(const string& _exp) :infix_expression(move(_exp)), postfix_expression()
{
infix_expression.shrink_to_fit();
}
Expression::~Expression()
{
infix_expression.~basic_string();
postfix_expression.~basic_string();
}
void Expression::convert_from_infix_to_postfix_notation()
{
stack<char> stack;
size_t size(infix_expression.size());
bool is_math_function(false);
size_t opened_left_brackets(0);
size_t current_math_function(0);
/*char* buffer;
const char* token = strtok_s(const_cast<char*>(infix_expression.c_str()), SPACE_C_STR, &buffer);
string str;*/
stack.push(SPACE);
/*while (token != nullptr)
{
str = token;
if (token[0] == Ï || isalnum(token[0])) postfix_expression.push_back+=str; postfix_expression.push_back(SPACE);
}*/
for (size_t i(0); i < size; ++i)
{
if (infix_expression[i] == Ï || isdigit(infix_expression[i]) || is_point(infix_expression[i]) ||
is_alpha(infix_expression[i]))
{
if (infix_expression[i] == COMA) postfix_expression.push_back(POINT); // ïðîâåðÿþ êàêîé ðàçäåëèòåëü èñïîëüçóåòñÿ. Åñëè ',' - ìåíÿþ íà '.'.(Îñòàëîñü ñ êîíñîëüíîé âåðñèè. Âåðîÿòíî â gui âåðñèè íå ïðèãîäèòñÿ.)
else
postfix_expression.push_back(infix_expression[i]); // åñëè ÷èñëî ñðàçó äîáàâëÿþ åãî â âûõîäíóþ ñòðîêó - postfix_expression.
}
else
{
if (infix_expression[i] == DEDACTION)
{
if (i == 0 || infix_expression[i - 1] == LEFT_BRACKET)
{
postfix_expression.push_back(DEDACTION); continue;
}
}
if (postfix_expression.size() > 0 && postfix_expression.back() != SPACE) postfix_expression.push_back(SPACE); // ìåæäó ñèìâîëàìè âûõîäíîé ñòðîêè ñòàâëþ ïî îäíîìó ïðîáåëó - ÷òî áû áûëî óäîáíåå ïàðñèòü.
if (infix_expression[i] == LEFT_BRACKET)
{
if (i != 0 && is_alpha(infix_expression[i - 1]))
{
++current_math_function;
postfix_expression.push_back(LEFT_FUNCTION_BRACKET);
postfix_expression.push_back(SPACE);
}
++opened_left_brackets;
}
if (infix_expression[i] == RIGHT_BRACKET) // Ïðîâåðêà ñêîáîê.
{
while (stack.top() != LEFT_BRACKET)
{
from_stack_to_out_str(postfix_expression, stack);
if (postfix_expression.back() != SPACE) postfix_expression.push_back(SPACE);
}
stack.pop();
if (current_math_function != 0 && opened_left_brackets == 1 || (current_math_function >= 2 && opened_left_brackets >= 2)) { postfix_expression.push_back(RIGHT_FUNCTION_BRACKET); --opened_left_brackets; --current_math_function; }
else --opened_left_brackets;
}
else // åñëè ýòî íå ñêîáêà - çíà÷èò ýòî îïåðàòîð, òîãäà ïðîâåðÿþ åãî ïðèîðèòåòíîñòü è äîáàâëÿþ ïîñëå ýòîãî â ñòåê.
{
if (stack.top() != SPACE)
{
if (priority(infix_expression[i]) <= priority(stack.top()) && (infix_expression[i] != LEFT_BRACKET))// ïðîâåðÿþ íå ÿâëÿþåòñÿ ëè âõîäíîé ñèìâîë ëåâîé ñêîáêîé, ÷òî áû íå ïîðòèëà ïðèîðèòåòíîñòü
{
from_stack_to_out_str(postfix_expression, stack);
if (postfix_expression.back() != SPACE) postfix_expression.push_back(SPACE);
}
}
stack.push(infix_expression[i]);
}
}
}
while (stack.size() > 1) //ïîþçàòü empty // âûòàëêèâàþ ýëåìåíòû èç ñòåêà â âûõîäíóþ ñòðîêó
{
if (postfix_expression.back() != SPACE) postfix_expression.push_back(SPACE);
from_stack_to_out_str(postfix_expression, stack);
}
postfix_expression.shrink_to_fit();
}
size_t Expression::priority(char functor) const
{
switch (functor)
{
case LEFT_BRACKET:
case RIGHT_BRACKET:
{return 1; break; };
case ADDITION:
case DEDACTION:
{return 2; break; };
case MULTIPLE:
case DIVISION:
{return 3; break; };
case POWER:
{ return 4; break; }
default: {return -1; }
}
}
void Expression::with_space(const string & exp, string & infix_expression)
{
size_t simbol = group_number(exp.begin()), current_simbol(0);
infix_expression.push_back(*exp.begin());
string::const_iterator pos;
for (pos = next(exp.begin()); pos != exp.end(); ++pos)
{
current_simbol = simbol_type(pos);
(simbol == current_simbol && (simbol != 3 || current_simbol != 3)) ? infix_expression.push_back(*pos) : infix_expression.push_back(SPACE); infix_expression.push_back(*pos);
simbol = current_simbol;
}
}
void Expression::from_stack_to_out_str(string& _postfix_expression, stack<char>& stack)
{
_postfix_expression.push_back(stack.top());
stack.pop();
}