-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
中缀表达式《==》后缀表达式.cpp
179 lines (154 loc) · 3.7 KB
/
中缀表达式《==》后缀表达式.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
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
#include <iostream>
#include <vector>
#include <string>
#include <stack>
using namespace std;
//判断是否为操作符
bool isOperator(char op)
{
return (op == '+' || op == '-' || op == '*' || op == '/');
}
//判断是否为数字
bool isDigit(char op)
{
return (op >= '0' && op <= '9');
}
//计算表达式结果
int cal(int left, int right, char op)
{
int res = 0;
if (op == '+')
res = left + right;
else if (op == '-')
res = left - right;
else if (op == '*')
res = left * right;
else if (op == '/')
res = left / right;
return res;
}
//判断运算符优先级
int pirority(char op)
{
if (op == '+' || op == '-')
return 1;
if (op == '*' || op == '/')
return 2;
else
return 0;
}
//逆波兰表达式转中缀表达式
int evalRPN(string &tokens)
{
if (tokens.size() <= 0)
return 0;
stack<int> s1;//创建辅助栈
int left = 0, right = 0;//定义左/右操作数
int result = 0;//定义中间结果
string temp;
for (unsigned int i = 0; i < tokens.size(); i++ )
{
if (isDigit(tokens[i]))//扫描数字入栈
{
temp.push_back(tokens[i]);
}
else if (tokens[i] == ' ')
{
if (temp.size() > 0) //防止运算符后面跟分隔符,所以判断一下temp里面是否有数字
{
s1.push(atoi(temp.c_str()));
temp.clear();
}
}
else if (isOperator(tokens[i]) && !s1.empty())
{
//防止数字后面直接跟运算符,所以这里也要判断一下temp是否还有数字没有提取出来
if (temp.size() > 0)
{
s1.push(atoi(temp.c_str()));
temp.clear();
}
right = s1.top();
s1.pop();
left = s1.top();
s1.pop();
result = cal(left, right, tokens[i]);
s1.push(result);
}
}
if (!s1.empty())
{
result = s1.top();
s1.pop();
}
return result;
}
//中缀表达式转逆波兰表达式
vector<char> infixToPRN(const string & token)
{
vector<char> v1;
int len = token.size();//string的长度
if (len == 0)
return v1;
stack<char> s1;//存放逆波兰式的结果
int outLen = 0;
for (int i = 0; i < len ; i++)
{
if (token[i] == ' ')//跳过空格
continue;
if (isDigit(token[i]) )//若是数字,直接输出
{
v1.push_back(token[i]);
}
else if (token[i] == '(')//如果是'(',则压栈
{
s1.push(token[i]);
}else if (token[i] == ')')//如果是')', 则栈中运算符逐个出栈并输出,直至遇到'('。 '('出栈并丢弃
{
while (s1.top() != '(')
{
v1.push_back( s1.top());
s1.pop();
}
s1.pop();//此时栈中为')',跳过
}
while (isOperator(token[i]))//如果是运算符
{
//空栈||或者栈顶为)||新来的元素优先级更高
if( s1.empty() || s1.top() == '(' || pirority(token[i]) > pirority(s1.top()))
{
s1.push(token[i]);// 当前操作符优先级比栈顶高, 将栈顶操作符写入后缀表达式
break;
}else
{
v1.push_back(s1.top());
s1.pop();
}
}
}
while (!s1.empty())//输入结束,将栈中剩余操作符出栈输出
{
v1.push_back(s1.top());
s1.pop();
}
return v1;
}
int main()
{
//vector<string> sRPN = {"4", "13", "5" , "/", "+"};//逆波兰表达式
//cout << "逆波兰表达式结果为:" << evalRPN(sRPN) <<endl;
//vector<string> fix = {"4", "+", "13", "/", "5"};//中缀表达式
string fix = "2+2*(1*2-4/2)*1";
vector<char> RPN = infixToPRN(fix);
string s_fix;
for (auto it = RPN.begin(); it != RPN.end(); it++)
{
cout << *it << " ";
s_fix += *it;
s_fix += " ";
}
cout << endl;
cout << "逆波兰表达式结果为:" << evalRPN(s_fix) << endl;
system("pause");
return 0;
}