输入中缀表达式转化为后缀表达式并求值


后缀表达式的运算毫无疑问是简易的,接下来讨论如何将中缀表达式转化为后缀表达式使其容易计算


中缀表达式转化为后缀表达式

从头到尾读取中缀表达式中的每个对象,对不同对象按不同的情况的处理。

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
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值