算法笔记 栈 中缀转后缀表达式 codeup 1918 简单计算器

13 篇文章 0 订阅
10 篇文章 0 订阅
#include <iostream>
#include <string>
#include <stack>
#include <queue>
#include <map>

using namespace std;

struct node{
    double num; //操作数
    char op;    //操作符
    bool flag;  //true表示操作数, false表示操作符
};

string str;
stack<node> s;      //操作符栈
queue<node> q;      //后缀表达式序列
map<char, int> op;  //操作符优先级栈

void eraseBlank(string &str){
    for(string::iterator it=str.end(); it!=str.begin(); it--){
        if(*it == ' ') str.erase(it);
    }
}

void change(){
    double num;
    struct node temp;
    for(int i=0; i<str.length();){
        if(str[i]>='0' && str[i]<='9'){         //如果是数字
            temp.flag = true;
            temp.num = str[i++] - '0';
            while(i<str.length() && str[i] >= '0' && str[i]<='9'){
                temp.num = temp.num * 10 + (str[i] - '0');
                i++;
            }
            q.push(temp);   //将操作数压入后缀表达式队列
        }else{              //如果是操作符
            temp.flag = false;
            //只要操作符栈不空, 而栈顶元素又比该操作符优先级高
            //就把操作符栈的栈顶元素弹出到后缀表达式队列中去
            while(!s.empty() && op[str[i]] <= op[s.top().op]){
                q.push(s.top());
                s.pop();
            }
            //现在操作符栈的栈顶运算符比待判定的运算符优先级低了
            //可以让该运算符入栈了
            temp.op = str[i];
            s.push(temp);
            i++;
        }
    }
    //字符串全部处理完了,如果操作符栈中还有操作符,
    //就把它们弹出到后缀表达式队列中去
    while(!s.empty()){
        q.push(s.top());
        s.pop();
    }
}

double cal(){
    double temp1, temp2;
    node cur, temp;
    while(!q.empty()){
        cur = q.front(); q.pop();   //记录 后缀表达式队列 的 队首元素
        if(cur.flag == true) s.push(cur);   //如果该队首元素是个符号, 就把这个元素放进操作符栈
        else{
            temp2 = s.top().num; s.pop();   //弹出第二操作数
            temp1 = s.top().num; s.pop();   //弹出第一操作数
            temp.flag = true;               //临时记录操作数
            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;
            s.push(temp);           //把计算结果压入操作符栈
        }
    }
    return s.top().num;
}

int main(){
    op['+'] = op['-'] = 1;
    op['*'] = op['/'] = 2;
    while(getline(cin, str), str!="0"){
        eraseBlank(str);                //清除字符串空格
        while(!s.empty()) s.pop();      //操作符栈清空
        change();                       //中缀表达式转后缀表达式
        printf("%.2f\n", cal());        //计算后缀表达式
        return 0;
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值