例如有表达式:9+(3-1)*3+10/2 这样叫做中缀表达式
如果用栈来解决这类问题,需要先变成后缀表达式(这是一种不需要括号的方法):" 9 3 1 — 3 * + 10 2 / +", 那怎么求这个呢?
1.求后缀表达式:将中缀表达式转化为后缀表达式(栈用来进出运算的符号):
从左到右遍历中缀表达式的每一个数字和符号,若是数字就输出,既成为后缀表达式的一部分,若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于栈顶符号(乘除优先加减),则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。(左右括号匹配后丢弃)
注意:加号遇到栈中的加号时,算栈中的加号优先级高,所以栈中的加号出栈,新的加号入栈
2.表达式运算:将后缀表达式进行运算得出结果(栈用来进出运算的数字)
从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。
下面是参照网上的代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<stack>
using namespace std;
stack<char> s;
stack<int> ss;
int main()
{
int len1, len2, len, i, j;
string str1, str2;//str1为中缀表达式,str2为后缀表达式
while (1){
//中缀表达式转换为后缀表达式
getline(cin, str1);
len1 = str1.length();
str2.clear();
for (i = 0; i < len1; i++){
if (str1[i] >= '0' && str1[i] <= '9')
str2.push_back(str1[i]);
else{
if (s.size() == 0 || str1[i] == '(')
s.push(str1[i]);
else{
char tmp1 = s.top();
if (str1[i] == ')'){
len = s.size();
while (len){
char tmp = s.top();
s.pop();
if (tmp == '(')
break;
else
str2.push_back(tmp);
len--;
}
}
else{
if (tmp1 == '*' || tmp1 == '/'){
if (str1[i] == '*' || str1[i] == '/')
s.push(str1[i]);
else{
len = s.size();
while (len){
char tmp = s.top();
str2.push_back(tmp);
s.pop();
len--;
}
s.push(str1[i]);
}
}
else{
s.push(str1[i]);
}
}
}
}
}
if (s.size() != 0){
len = s.size();
while (len){
char tmp = s.top();
str2.push_back(tmp);
s.pop();
len--;
}
}
cout << str2 << endl;
//由后缀表达式计算结果
int temp1, temp2, temp3;
len2 = str2.length();
for (i = 0; i < len2; i++){
if (str2[i] >= '0' && str2[i] <= '9'){
int t = str2[i]-48;
ss.push(t);
}
else{
temp1 = ss.top();
ss.pop();
temp2 = ss.top();
ss.pop();
if (str2[i] == '+'){
temp3 = temp2 + temp1;
}
else if (str2[i] == '-'){
temp3 = temp2 - temp1;
}
else if (str2[i] == '*'){
temp3 = temp2 * temp1;
}
else if (str2[i] == '/'){
temp3 = temp2 / temp1;
}
ss.push(temp3);
}
}
cout << ss.top() << endl;
}
system("pause");
}