简易计算器_中缀表达式转后缀表达式 (STL应用)&&(包含英文括号,有错误请打我)

本文介绍了如何使用C++ STL实现中缀表达式到后缀表达式的转换,包括处理英文括号的情况。通过介绍算法原理和代码实现,帮助读者理解表达式转换的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<cstdio>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<iostream>
#include<algorithm>
using namespace std;

struct node
{
    double num;
    char op;
    bool flag;
};              //错误点: 建立了一个真的node,以下的类型定义都是node,导致了错误

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

void change()   //中缀表达式转后缀表达式
{
    int i = 0;
    while(i < str.length())
    {
        node temp, cur;
        //区分操作数和操作符
        if(str[i] >= '0' && str[i] <= '9') //num 接收到整数,并存入node,压入栈
        {
            temp.num = str[i++] - '0';
            while(str[i] >= '0' && str[i] <= '9' && i < str.length())
            {
                temp.num = temp.num * 10 + (str[i] - '0');
                i++;
            }
            temp.flag = true;
            q.push(temp);
        }
        else    //op 和栈顶元素比较优先级,如果高,则入栈;如果<=则将栈顶元素弹出,op入站,要循环直到栈空或op优先级大于栈顶
        {
            temp.flag = false;
            temp.op = str[i];
            if(temp.op=='(')
            {
                s.push(temp);
                i++;
            }
            else if(temp.op==')')    //右括号是不入栈的
            {
                while(!s.empty()&&s.top().op!='(')
                {
                    q.push(s.top());
                    s.pop();
                }
                if(!s.empty()&&s.top().op=='(')
                    s.pop();
                i++;
            }
            else
            {
                while(!s.empty()&&op[str[i]] <= op[s.top().op])
                //错误点1:op[s.top()]
                //错误点2:忘了判断s是否空
                //错误点3:判断s非空需要放在另一个条件前面
                //错误点4:要循环啊!!!!
                {
                    q.push(s.top());
                    s.pop();
                }
                s.push(temp);   //如果当前op不是括号,那不管加减乘除都要入栈,区别在于和栈顶元素比较后的操作
                i++;
            }
        }
    }

    while(!s.empty())
    {
        q.push(s.top());
        s.pop();
    }
}

double cal()
{
    node temp,cur,c1;
    double n1,n2;
    while(!q.empty())
    {
        cur=q.front();
        q.pop();
        if(cur.flag)   //如果是操作数
            s.push(cur);

        else    //如果是op
        {
            //从栈中弹出两个操作数
            //cout<<cur.op<<" ";
            n2=s.top().num;
            s.pop();
            n1=s.top().num;
            s.pop();
            //cout<<n1<<" "<<n2<<" "<<cur.op<<endl;
            if(cur.op=='+') temp.num=n1+n2;
            else if(cur.op=='-')    temp.num=n1-n2;
            else if(cur.op=='*')    temp.num=n1*n2;
            else if(cur.op=='/')    temp.num=n1/n2;
            temp.flag=true;
            s.push(temp);
        }
    }

    return s.top().num;

}

int main()
{
    op['+'] = op['-'] = 1;
    op['*'] = op['/'] = 2;

    while(getline(cin, str), str != "0")
    {
        //去掉空格
        for(string::iterator it = str.end(); it != str.begin(); it--)
            if(*it == ' ')      //错误点:" " 又是双引号的错误
                str.erase(it);
        //cout<<str<<endl;
        change();
        printf("%.2f\n", cal());
        //错误点:每次都要清空一下栈和队列啊少年!!!
        while(!s.empty())
            s.pop();
        while(!q.empty())
            q.pop();
    }
    return 0;
}

// 带括号的样例:(56-20)/(4+2)
//不带括号的样例:30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
//12178.21

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值