后缀表达式的运算毫无疑问是简易的,接下来讨论如何将中缀表达式转化为后缀表达式使其容易计算
中缀表达式转化为后缀表达式
从头到尾读取中缀表达式中的每个对象,对不同对象按不同的情况的处理。
1.运算数:直接输出;
2.左括号:压入堆栈(左括号在进栈前优先级最高,进栈后优先级最低)
3.右括号:将栈顶的运算符弹出并且输出只要遇到了左括号(左括号不输出,出栈即可,栈中不会出现右括号)
4.运算符
- 若优先级大于栈顶运算符,将其压栈
- 若优先级小于等于栈顶运算符,将栈顶运算符弹出并输出,直到遇见栈顶的运算符优先级小于自己,进栈
5.若各对象处理完毕,将堆栈中保留的运算符一并输出
c++实现
#include<iostream>
#include<string>
using namespace std;
template<class Type>
class SeqStack{
public:
int maxsize;
Type* base; // 栈底指针
int top; // 栈顶指针
SeqStack(int size=100):maxsize(size) // 初始化列表
{
base = new Type[maxsize];
if(base == NULL){ cout<<"内存分配失败"<<endl;}
top = 0;
} // 构造函数 空间大小为size
~SeqStack()
{
delete base;
}
bool empty();
bool full();
void SeqStackClear(); // 将栈清空
int SeqStackLength(); // 栈中元素的个数
void Push(Type e); // 插入栈顶
Type Pop(); // 出栈,删除并返回其值
Type GetTop(); // 返回栈顶元素
};
template<class Type>
bool SeqStack<Type>::empty()
{
if(top == 0)
return true;
else
return false;
}
template<class Type>
bool SeqStack<Type>::full()
{
if(top==maxsize)
return true;
else
return false;
}
template<class Type>
void SeqStack<Type>::SeqStackClear()
{
top = 0;
return ;
}
template<class Type>
int SeqStack<Type>::SeqStackLength()
{
return top;
}
template<class Type>
void SeqStack<Type>::Push(Type e)
{
if(full())
{
cout<<"栈空间已满"<<endl;
return;
}
else{
top++;
base[top] = e;
}
return;
}
template<class Type>
Type SeqStack<Type>::Pop()
{
if(empty()){cout<<"栈空"<<endl; exit(0);}
else
{
Type p = base[top];
top--;
return p;
}
}
template<class Type>
Type SeqStack<Type>::GetTop()
{
return base[top];
}
int getPriority(string s)
{
if(s == "^") return 3;
if(s == "*" || s == "/") return 2;
if(s == "+" || s == "-") return 1;
if(s == "(") return 0; // 左括号栈外优先级最高,栈内优先级最低,因此一定压栈
}
int main()
{
string s;
cin>>s; // 输入一个中缀表达式
SeqStack<string> stack_1; // 暂存操作符,栈的规模式100
SeqStack<string> stack_2; // 暂存操作数
for(int i = 0; i < s.length(); i ++) // 遍历中缀表达式
{
if(s[i] >= '0' && s[i] <= '9')
{
int k = 1;
while(s[i+k] >= '0' && s[i+k] <= '9')
k++;
string opd = s.substr(i,k);
stack_2.Push(opd);
i = i + k -1;
}
else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'||s[i]=='('||s[i]==')')
{
if(stack_1.empty()) stack_1.Push(s.substr(i,1)); // 若操作符栈为空,压栈
else{
if(s[i]=='(') {stack_1.Push(s.substr(i,1));} // 左括号一定入栈
else if(s[i] == ')') // 右括号,则弹出操作符栈至左括号
{
while(stack_1.GetTop()!="(")
stack_2.Push(stack_1.Pop());
stack_1.Pop();
}
else if(getPriority(s.substr(i,1)) > getPriority(stack_1.GetTop()))
stack_1.Push(s.substr(i,1));
else if(getPriority(s.substr(i,1)) <= getPriority(stack_1.GetTop()))
{
do{
stack_2.Push(stack_1.Pop());
}while(getPriority(s.substr(i,1)) <= getPriority(stack_1.GetTop())); // 知道该运算符优先级大于栈顶运算符
stack_1.Push(s.substr(i,1));
}
}
}
}
// 遍历完中缀表达式后,将操作符栈中剩余操作符转移到操作数栈
while(!stack_1.empty())
{
stack_2.Push(stack_1.Pop());
}
while(!stack_2.empty())
{
stack_1.Push(stack_2.Pop());
}
cout<<"后缀表达式为:";
while(!stack_1.empty())
{
cout<<stack_1.GetTop()<<" ";
stack_2.Push(stack_1.Pop());
}
cout<<endl;
while(!stack_2.empty())
{
stack_1.Push(stack_2.Pop());
}
SeqStack<int> stack_3; // 存放计算结果
while(!stack_1.empty())
{
if(stack_1.GetTop()[0]<='9'&&stack_1.GetTop()[0]>='0')
{
stack_3.Push(atoi(stack_1.Pop().c_str()));
}
else{
int b = stack_3.Pop();
int a = stack_3.Pop();
string opt = stack_1.Pop();
if(opt == "+") stack_3.Push(a+b);
if(opt == "-") stack_3.Push(a-b);
if(opt == "*") stack_3.Push(a*b);
if(opt == "/") stack_3.Push(a/b);
}
}
cout<<"计算结果为:";
cout<<stack_3.GetTop()<<endl;
return 0;
}
样例输出
10*(2+3)/5-10
后缀表达式为:10 2 3 + * 5 / 10 -
计算结果为:0