问题:给定一个可能包含字母、数字(正负数)的中缀表达式,请将其转化为后缀表达式
· 核心思想:利用栈来实现该操作。
1.数据准备:
首先定义两个string类型的变量str和ans,分别用来存储所给的中缀表达式和最后要输出的后缀表达式。
定义一个栈stk,用来执行中缀变后缀的相关操作。
2.判定优先级:
在前缀转中缀的过程中,是通过计算各运算符的优先级来进行的,因此需要设计一个函数,用来判定某个运算符的优先级。
预设“+”和“-”的优先级为2,“*”和“/”的优先级为3,“^”的优先级为4,其余如括号等的优先级设定为1.
因此,传入所给的运算字符ch,通过该函数,可依据ch的类型返回其优先级。
3.算法思想:
①去除所给表达式str中的所有空格;
②遍历str表达式:
· 如果检测到数字或字母,直接加入后缀表达式中;
· 如果检测到字符,判定其类型:
若为“(”,入栈;若为“)”,则依次将栈中的运算符加入后缀表达式,直到出现“(”,并从栈中删除“(”。
若为“+”,则首先判定其是否是“表示正数”的加号。若其为运算加号,则判定是否高于栈顶元素优先级,高于则入栈;若为“-”,则首先判定其是否是“表示负数”的减号。若其为运算减号,则判定是否高于栈顶元素优先级,高于则入栈;若为其余运算符,直接判断是否高于栈顶元素优先级,高于则入栈。
若“+”、“-”、其余运算符优先级低于栈顶元素,则依次弹出栈顶运算符并加入后缀表达式,直到一个优先级比它低的运算符或“(”为止。
③遍历完成,若栈非空,依次弹出栈中所有元素并加入后缀表达式。
该算法使得栈顶运算符处于较高优先级,并先弹出栈,进入后缀表达式。在执行完上述操作后,也就得到了最后要转化的后缀表达式。
难点:
假若给予的中缀表达式包含正负数,如何判断正号符号表示的是运算还是正负数的判定符
假若给予的中缀表达式存在空格,如何消除空格影响
代码:
#include <bits/stdc++.h>
using namespace std;
// 判定运算符的优先级
int prior(char x)
{
if(x=='*'||x=='/') return 3;
else if(x=='+'||x=='-') return 2;
else if(x=='^') return 4;
else return 1;
}
void solve()
{
string str;
string ans;
// 用getline读入表达式,防止空格影响
getline(cin, str);
// 去除表达式里的空格
str.erase(remove(str.begin(), str.end(), ' '), str.end());
stack<char> stk;
// 遍历表达式,执行转化操作
for(int i = 0;i < str.size();i++)
{
char ch = str[i];
// 如果是数字、字母,则直接加到后缀表达式里
if(ch >= '0' && ch <= '9')
{
ans += ch;
}
else if(ch >= 'A' && ch <= 'Z')
{
ans += ch;
}
else if(ch >= 'a' && ch <= 'z')
{
ans += ch;
}
else
{
// 如果是'(',直接入栈
if(ch == '(')
{
stk.push(ch);
}
// 如果是')',则将栈中运算符依次读出,加入后缀表达式,直到遇到'('或栈空
else if(ch == ')')
{
while(!stk.empty() && stk.top() != '(')
{
ans += stk.top();
stk.pop();
}
// 别忘了弹出最后的左括号
stk.pop();
}
// 如果是减号,先要判定是表示运算还是表示正负数
else if(ch == '-')
{
// 如果是表示正负号,直接加入表达式
if(!(str[i-1] >= '0' && str[i-1] <= '9'))
{
ans += '-';
}
// 如果是表示运算,就判定其优先级,直到遇到优先级更低的运算符或'('
else
{
while(!stk.empty() && stk.top() != '(')
{
if(prior(stk.top()) >= prior(ch))
{
ans += stk.top();
stk.pop();
}
else
break;
}
stk.push(ch);
}
}
// 加号和减号同理
else if(ch == '+')
{
if(!(str[i-1] >= '0' && str[i-1] <= '9'|| str[i-1] == ')'))
{
continue;
}
else
{
while(!stk.empty() && stk.top() != '(')
{
if(prior(stk.top()) >= prior(ch))
{
ans += stk.top();
stk.pop();
}
else
break;
}
stk.push(ch);
}
}
// 如果是剩下的运算符
else
{
while(!stk.empty() && stk.top() != '(')
{
if(prior(stk.top()) >= prior(ch))
{
ans += stk.top();
stk.pop();
}
else
break;
}
stk.push(ch);
}
}
}
// 最后将栈中剩余的元素全部弹出
while(!stk.empty())
{
ans += stk.top();
stk.pop();
}
cout << ans << endl;
// 测试用
// cout << str << endl;
}
int main()
{
int t = 1;
for(int i = 1;i <= t;i++)
{
solve();
}
return 0;
}
如有问题,随时欢迎指出~(՞• •՞)