栈---逆波兰表达式(RPN)的计算

表达式


表达式 = 操作数(运算对象) + 操作符(运算符) + 分界符
算数表达式有三种表示:(逆波兰表达式又称为后缀表达式)

  • 中缀表达式(infix):<操作数><操作符><操作数>例如:A+B
  • 前缀表达式(prefix):<操作符><操作数><操作数>例如:+AB
  • 后缀表达式(postfix):<操作数><操作数><操作符>例如:AB+

C++中操作符的运算优先级:

优先级1234567
操作符单目一,!*,/%+/-<,<=,>=,>==,!=&&||

由于中缀表达式有操作符优先级问题,需要使用两个栈才能解决问题,所以一般使用后缀表达式进行计算。
这里写图片描述

详解后缀表达式

A B C D - * + E F / -

步骤输入项项类型操作栈内容
1置空栈
2A操作数进栈A
3B操作数进栈A B
4C操作数进栈A B C
5D操作数进栈A B C D
6-操作符D,C出栈,计算C-D,结果R1进栈A B R1
7*操作符R1,B出栈,计算B*R1,结果R2进栈A R2
8+操作符R2,A出栈,计算A+R2,结果R3进栈R3
9E操作数进栈R3 E
10F操作数进栈R3 E F
11/操作符F,E出栈,计算E/F,结果R4进栈R3 R4
12-操作符R4,R3出栈,计算R3-R4,结果R5进栈R5

代码实现

#include<stdlib.h>
#include<iostream>
#include<stack>
#include<ctype.h>
using namespace std;


class Calculator{
public:
    //构造函数
    Calculator()
    {}
    void Run();//执行表达式计算---后缀表达式
    void clear();//清除栈空间

private:
    stack<double> s;
    void AddOperand(double value);//操作数进栈
    bool Get2Operand(double& left, double& right);//两个操作数出栈
    void DoOperand(char op);//形成运算指令,进行计算
};


//操作数进栈
void Calculator::AddOperand(double value){
    s.push(value);//将操作数进栈  
}

//两个操作数出栈
bool Calculator::Get2Operand(double& left, double& right){
    if (s.empty() == true)//判断栈是否为空
    {
        cout << "缺少右操作数!" << endl;
        return false;
    }
    right = s.top();
    s.pop();
    if (s.empty() == true)//判断栈是否为空
    {
        cout << "缺少左操作数!" << endl;
        return false;
    }
    left = s.top();
    s.pop();
    return true;
}

//形成运算指令,进行计算
void Calculator::DoOperand(char op){
    double left, right;//待计算的左值和右值
    double result;//计算的结果
    if (Get2Operand(left, right) == true){
        switch (op){
        case '+':
            result = left + right;
            s.push(result);
            break;
        case '-':
            result = left - right;
            s.push(result);
            break;
        case '*':
            result = left * right;
            s.push(result);
            break;
        case '/':
            if (right == 0.0){//除法运算时,右值不能为零
                cerr << "右值为零!" << endl;
                clear();
            }
            else{
                result = left / right;
                s.push(result);
            }
            break;
        default:
            clear();
        }
    }
    else
        clear();
}

//读字符串并求一个后缀表达式的值,以字符'='结束
void Calculator::Run(){
    char ch;
    double newOperand;
    while (cin >> ch, ch != '='){//读入字符
        switch(ch){
        case'+':case'-':case'*':case'/'://判断是否为操作符
            DoOperand(ch);
            break;
        default:
            cin.putback(ch);//将ch放回,以便重新以double类型读入
            cin >> newOperand;
            AddOperand(newOperand);
        }
    }
    if (ch == '=')
    {
        newOperand = s.top();
        cout << newOperand << endl;
    }

}

//清除栈空间
void Calculator::clear(){
    s.empty();
}


int main()
{
    Calculator c;
    while (1){
        cout << "请输入操作数和操作符,以'='结束:" << endl;
        c.Run();
        c.clear();
        fflush(stdin);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值