算法笔记 栈的应用 简单计算器 中缀和后缀表达式

18 篇文章 0 订阅
11 篇文章 0 订阅

思路

  • 将输入的中缀表达式转后缀表达式
    • 遇到数字,则算出数值,直接放入队列(注意数据非仅有一位,需要计算出整个数的值)
    • 遇到运算符先判断优先级是否小于栈中top的运算符
      • 如果是,将栈中的运算符pop到队列中,直到栈中没有运算符优先级更大为止
      • 如果不是,则直接将运算符放入栈中
    • 最后如果栈中剩余运算符,则直接放入队列中
  • 计算后缀表达式,遍历队列
    • 如果为数值,则放入栈中
    • 如果为运算符
      • 从栈中pop出两个数(注意是先第二个后第一个,后进先出嘛)
      • 随后运算
      • 最后把计算完成的数放入栈中

代码

#include <iostream>
#include <stdio.h>
#include <stack>
#include <queue>
#include <map>
using namespace std;

struct node{
    int flag;//区别操作数和操作符
    double num;
    char op;//操作符
};

stack<node> opers;
queue<node> behind;
string middle;
map<char,int> op;

void Change(){//把中缀表达式转后缀表达式
    for(int i=0;i<middle.length();){
        node temp;
        temp.flag=1;
        if(middle[i]>='0'&&middle[i]<='9'){
            temp.num=middle[i]-'0';
            i++;
            while(i<middle.length()&&middle[i]>='0'&&middle[i]<='9'){
                temp.num=temp.num*10+middle[i]-'0';
                i++;
            }
            behind.push(temp);
        }
        else{
            temp.flag=0;
            while(!opers.empty()&&op[middle[i]]<=op[opers.top().op]){//如果操作符优先级低于操作符栈
                behind.push(opers.top());
                opers.pop();
            }
            temp.op=middle[i];
            opers.push(temp);
            i++;
        }
    }
    //如果最后栈中还有操作符,直接压入
    while(!opers.empty()){
        behind.push(opers.top());
        opers.pop();
    }
}

double Cal(){//计算后缀表达式
    double temp1,temp2;
    node cur,temp;
    while(!behind.empty()){
        cur=behind.front();//记录队首元素
        behind.pop();
        if(cur.flag==1)//是数
            opers.push(cur);
        else{
            temp2=opers.top().num;
            opers.pop();
            temp1=opers.top().num;
            opers.pop();
            temp.flag=1;
            if(cur.op=='+') temp.num=temp1+temp2;
            else if(cur.op=='-') temp.num=temp1-temp2;
            else if(cur.op=='*') temp.num=temp1*temp2;
            else temp.num=temp1/temp2;
            opers.push(temp);
        }
    }
    return opers.top().num;
}

int main(){
    op['+']=op['-']=1;
    op['*']=op['/']=2;
    while(getline(cin,middle)&&middle!="0"){
        //注意从右到左遍历
        for(string::iterator it=middle.end(); it!=middle.begin();it--){
            if(*it==' ')//忽略空格键
                middle.erase(it);
        }
        while(!opers.empty())   opers.pop();//初始化栈
        Change();
        printf("%.2lf\n",Cal());
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值