m0_63626848 2022-06-10 14:06 采纳率: 55.6%
浏览 49
已结题

怎么用栈写一个计算器

要求是能够进行+-*%以及括号,输入的式子在10000位以内。输入的是中缀表达式,我的思路是转后缀表达式。但是没怎么学会。而且还要提示异常输入。最麻烦的是数字和运算符之间可能有空格!

  • 写回答

1条回答 默认 最新

  • 白驹_过隙 算法领域新星创作者 2022-06-10 15:00
    关注

    img

    #include<cstdio>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<stack>
    using namespace std;
    struct node
    {
        double num;
        char op;
        bool flag;  //true 为数字
    };
    stack<node> st;
    queue<node> q;
    map<char,int> mp;
    string str;
    void Change()  //中缀转后缀
    {
        node temp,tempst;       //temp用于存队首元素,tempst存栈顶元素
        for(int i = 0;i < str.length();)
        {
            if(str[i]>='0'&&str[i]<='9')  //如果是数字
            {
                temp.num = str[i] - '0';
                temp.flag = true;
                i++;
                while(i < str.length() && str[i]>='0' && str[i] <= '9')  //数字可能不止一位
                {
                    temp.num = temp.num * 10 + str[i] - '0';
                    i++;
                }
                q.push(temp);
            }
            else                //是运算符
            {
                temp.op = str[i];
                temp.flag = false;
                if(!st.empty())
                    tempst = st.top();
                while(!st.empty() && mp[temp.op] <= mp[tempst.op]) //与栈顶运算符优先级比较
                {                                    // 只有优先级大于栈顶操作符才直接入栈,否则将栈中操作符压入队列
                    q.push(tempst);
                    st.pop();
                    if(!st.empty())
                    {
                        tempst=st.top();
                    }
                }
                st.push(temp);
                i++;
            }
        }
        while(!st.empty())
        {
            q.push(st.top());
            st.pop();
        }
    }
    
    double Cal ()            //计算
    {
        double num1,num2,num;
        node temp,tempst;
        while(!q.empty())
        {
            temp = q.front();
            if(temp.flag == true)            //队首是数字,压入栈zhong
            {
                st.push(temp);
            }
            else                            //是运算符,从栈中弹出两个数字
            {
                tempst = st.top();
                num2 = tempst.num;
                st.pop();
                tempst = st.top();
                num1 = tempst.num;
                st.pop();
                if(temp.op == '+')    num = num1 + num2;
                else if(temp.op == '-') num = num1 - num2;
                else if(temp.op == '*') num = num1 * num2;
                else if(temp.op == '/') num = num1 / num2;
                temp.num = num;
                temp.flag = true;
                st.push(temp);
            }
            q.pop();
        }
        temp = st.top();
        return temp.num;
    }
    int main(void)
    {
        mp['+'] = mp['-'] = 0;
        mp['*'] = mp['/'] = 1;
        double num;
        while(getline(cin,str),str!="0")
        {
            for(string::iterator it = str.begin();it!=str.end();it++)
            {
                if(*it == ' ')
                    str.erase(it);
            }
            while(!st.empty())
                st.pop();
            Change();
            num = Cal();
            printf("%.2f\n",num);
        }
        return 0;
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 6月19日
  • 已采纳回答 6月11日
  • 创建了问题 6月10日

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分