1、中缀表达式转后缀表达式
在编程实现四则运算时,往往需要两个步骤:(1)将题目给的中缀表达式转为后缀表达式;(2)利用后缀表达式进行计算;
对于1+(2-3)*4+10/5
准备一个栈用于存放符号,对于数字就输出,对于符号A,如果A的优先级大于栈内符号,那么A就入栈,如果栈内没有比A优先级小的符号,那么栈内的符号就出栈,再把A入栈。对于括号就入栈,一直匹配到右括号再将括号里的符号出栈。另外,还需要把表达式的[]{}这些符号要提前转化为()。
1、输出1,+入栈,此时后缀表达式是1
2、此时遇到左括号,(要入栈;然后输出2;下一个-入栈;输出3;一直匹配到右括号,再把括号内的符号出栈。此时后缀表达式是1 2 3
3、匹配到右括号,那么就把-弹出来;此时后缀表达式是1 2 3 -
4、下一个是乘号,优先级大于+号,入栈;此时后缀表达式是1 2 3 -
5、 接下来是4,输出;下一个是+号,此时栈内没有比它优先级小的符号,这样就把栈内的符号都弹出来,再把+入栈;此时后缀表达式是1 2 3 - 4 * +,栈里面就是+
6、接下来是10,输出;然后是/,大于栈内优先级,入栈;此时后缀表达式是1 2 3 - 4 * + 10
7、接下来是5,输出;此时栈内是/ +,全部输出;那么此时后缀表达式是1 2 3 - 4 * + 10 5 / +
2、HJ50
#include<iostream>
#include<string>
#include<stack>
#include<vector>
#include<sstream>
using namespace std;
//将大括号变成小括号,负数转化为0与之的差
void change(string &str)
{
for (int i = 0; i < str.size(); ++i)
{
if (str[i] == '{')//将‘{、}、[,]’替换成'()'
str[i] = '(';
else if (str[i] == '}')
str[i] = ')';
else if (str[i] == '[')
str[i] = '(';
else if (str[i] == ']')
str[i] = ')';
else if (str[i] == '-')
{
if (i == 0)//将'-'前面添加0转变成减法运算
str.insert(0, 1, '0');
else if (str[i - 1] == '(')
str.insert(i, 1, '0');
}
}
}
//根据当前遍历符号与栈顶元素的优先级判断符号是不是要出栈或进栈
//如果现在的优先级高输出false,否则输出true
bool Judge(char top, char now)
{
if ((top == '+' || top == '-') && (now == '+' || now == '-'))
return true;
else if ((top == '*' || top == '/') && (now == '+' || now == '-' || now == '*' || now == '/'))
return true;
else if (now == ')')//以便去匹配此前的“(”
return true;
return false;
}
//将中缀表达式转换为后缀表达式
//用string无法处理连续数字
vector<string> z_h(string &str1)
{
stack<char> sta;//初始化一空栈,用来对符号进出栈使用
//string str2;//作为后缀表达式
vector<string> str2;
for (int i = 0; i < str1.size(); i++)
{
string temp = "";
if (str1[i] >= '0' && str1[i] <= '9')//如果是数字就输出
{
temp += str1[i];
while (i + 1 < str1.size() && str1[i + 1] >= '0' && str1[i + 1] <= '9')
{
temp += str1[i + 1];//若是连续数字
++i;
}
str2.push_back(temp);
}
else if (sta.empty() || str1[i] == '(')//“(”,依然是符号,因其只是左括号,还没有配对,故进栈
sta.push(str1[i]);
else if (Judge(sta.top(), str1[i]))//若栈顶元素优先级较高,栈顶元素出栈
{
//接下来遇到符号“)”,需要去匹配此前的“(”,所以栈顶依次出栈,并输出,直到“(”出栈为止,将“(”
//上面的符号依次输出到str2里面
if (str1[i] == ')')
{
while (!sta.empty() && sta.top() != '(')
{
temp += sta.top();
sta.pop();
str2.push_back(temp);
temp = "";
}
sta.pop();//将“(”弹出来
}
//接下来对于不是括号的,判断优先级,如果高就入栈,直到当前字符低于栈顶的优先级
else
{
while (!sta.empty() && Judge(sta.top(), str1[i]))
{
temp += sta.top();
sta.pop();
str2.push_back(temp);
temp = "";
}
sta.push(str1[i]);//优先级高于栈顶,入栈
}
}
else//当前字符优先级更高
sta.push(str1[i]);
}
//接下来,弹出剩余的运算符
while (!sta.empty())
{
string temp = "";
temp += sta.top();
sta.pop();
str2.push_back(temp);
}
return str2;
}
//通过获得的后缀表达式计算结果
int cal(vector<string> & str)
{
stack<int> st3;//存放运算结果
int temp1, temp2,num;//其中temp1和temp2为栈顶的两个数
for (int i = 0; i < str.size(); i++)
{
string temp = str[i];
if (temp[0] >= '0' && temp[0] <= '9')
{
stringstream ss;
ss << temp;
ss >> num;
st3.push(num);
}
/*
string temp=str[i];
if(temp[0]>='0' && temp[0]<='9')//如果当前字符串是数字,利用字符串流转化为int型
{
stringstream ss;
ss<<temp;
ss>>num;
st.push(num);
}*/
else
{
temp1 = st3.top();
st3.pop();
temp2 = st3.top();
st3.pop();
if (str[i] == "+") st3.push(temp1 + temp2);
else if (str[i] == "-") st3.push(temp2 - temp1);
else if (str[i] == "*") st3.push(temp2 * temp1);
else if (str[i] == "/") st3.push(temp2 / temp1);
}
}
return st3.top();
}
int main()
{
string str;
while (getline(cin, str))
{
vector<string> vstr;
change(str);
vstr=z_h(str);
cout << cal(vstr);
}
}