狛 枝 凪 斗 2022-02-17 22:56 采纳率: 80%
浏览 22
已结题

关于用栈实现简易计算器 我的代码错在哪里?

问题遇到的现象和发生背景

进行两个数字之间的运算没有问题,如1 + 1,1 * 1,但是设计第三个数字,如1 + 1 + 1,就会没有输出结果就结束运行。

问题相关代码,请勿粘贴截图
#include<iostream>
#include<cstdio>
#include<map>
#include<string>
#include<stack>

using namespace std;

void deal(char c,stack<double>&num){
    double f1,f2;
    f2=num.top();
    num.pop();
    f1=num.top();
    num.pop();
    //栈后进先出 所以先出来的是f2
    double ans;
    if(c=='+')ans=f1+f2;
    if(c=='-')ans=f1-f2;
    if(c=='*')ans=f1*f2;
    if(c=='/')ans=f1/f2;
    num.push(ans);
}

int main(){
    string s;
    while(getline(cin,s),s!="0"){//双引号 不是单引号
    //式子中间可能有空格 不能用cin要用getline
        stack<double>num;
        stack<char>op;
        map<char,int>mp;
        mp['+']=mp['-']=1;
        mp['*']=mp['/']=2;
        double now=0;
        int i;
        for(i=0;i<=s.size();i++){
            if(s[i]>='0'&&s[i]<='9'){
                now=now*10+(s[i]-'0');
            }else if(i==s.size()){
                num.push(now);
            }else if(s[i]=='+'||s[i]=='*'||s[i]=='-'||s[i]=='/'){
                num.push(now);
                now=0;
                if(!op.empty()){
                //用top前必须判断非空!!!
                    while(mp[s[i]]<=mp[op.top()]&&(!op.empty())){
                        deal(op.top(),num);
                        op.pop();
                    }
                }
                op.push(s[i]);
            }//else if(s[i]==' ')continue;
        }
        while(!op.empty()){
            deal(op.top(),num);
            op.pop();
        }
        printf("%.2f\n",num.top());
    }
    return 0;
}


  • 写回答

2条回答 默认 最新

  • bostonAlen 2022-02-17 23:37
    关注
    if(!op.empty()){
                    //用top前必须判断非空!!!
                        while(mp[s[i]]<=mp[op.top()]&&(!op.empty())){
                            deal(op.top(),num);
                            op.pop();
                        }
                    }
    

    第一次进入while,op的大小是1,op内容为'+', 执行pop()后,op大小为0,第一次while结束,第二次进入while时候op是空的,所以第二次在while中使用mp[op.top()]时,
    op.top()访问失败,再检查下自己的逻辑吧。

    这里有个网上的,可以看看

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_LEN  200
    
    #pragma warning(disable:4996)
    
    //判断字符是否合理 0-9 . + - * / 
    bool CheckInput(char c)
    {
        //0-9
        if (0x30 <= c && c <= 0x39)
        {
            return true;
        }
        //. + - * /
        if (c == 0x2E || c == 0x2B || c == 0x2D || c == 0x2A || c == 0x2F)
        {
            return true;
        }
        return false;
    }
    
    bool IsNum(char c)
    {
        //0-9
        if (0x30 <= c && c <= 0x39)
        {
            return true;
        }
        //. + - * /
        if (c == 0x2E)
        {
            return true;
        }
        return false;
    }
    bool IsOperate(char c)
    {
        // + - * /
        if (c == 0x2B || c == 0x2D || c == 0x2A || c == 0x2F)
        {
            return true;
        }
        return false;
    }
    
    
    //1.判断表达式是否合理,2.判断数值是否合理 
    
    int main(int argc, char**argv)
    {
        printf("欢迎使用计算器\n");
        while (true)
        {
            printf("==========================\n");
            printf("请输入你的计算公式:\n");
            char szBuf[MAX_LEN] = { '\0' };
            memset(szBuf, 0, MAX_LEN);
            scanf("%s", szBuf);
            int len = strlen(szBuf);
            //校验用户输入字符是否正确 
            for (int i = 0; i < len; i++)
            {
                if (false == CheckInput(szBuf[i]))
                {
                    printf("Input Error charater.\n");
                    return -1;
                }
            }
            printf("You Input:%s\n执行计算中,请稍后...\n", szBuf);
            //解析表达式
            //计算值 
            double *pValues = (double *)malloc(sizeof(double));
            int     iValueIndex = 0;
            //操作符 
            char* pOpera = (char*)malloc(sizeof(char));
            int iOperaIndex = 0;
    
            int valIndex = 0;
            double fPreValue = 0;
            char szTemp[MAX_LEN];
            memset(szTemp, 0, MAX_LEN);
            for (int i = 0; i < len; i++)
            {
                if (IsNum(szBuf[i]))
                {
                    szTemp[valIndex++] = szBuf[i];
                    continue;
                }
                szTemp[valIndex++] = '\0';
                fPreValue = atof(szTemp);
                valIndex = 0;
                //存储计算值
                pValues[iValueIndex] = fPreValue;
                iValueIndex++;
                pValues = (double *)realloc(pValues, (iValueIndex + 1) * sizeof(double));
                //存储操作符
                pOpera[iOperaIndex] = szBuf[i];
                iOperaIndex++;
                pOpera = (char *)realloc(pOpera, (iOperaIndex + 1) * sizeof(char));
            }
            szTemp[valIndex++] = '\0';
            fPreValue = atof(szTemp);
            pValues[iValueIndex] = fPreValue;
    
            //执行*/计算 //10*20/23
            double dTemp = 0;
            for (int i = 0; i < iOperaIndex; i++)
            {
                if (pOpera[i] == 0x2A) //*
                {
                    dTemp = pValues[i] * pValues[i + 1];
                    pValues[i] = 0;
                    pValues[i + 1] = dTemp;
                }
                else if (pOpera[i] == 0x2F) //  /
                {
                    dTemp = pValues[i] / pValues[i + 1];
                    pValues[i] = 0;
                    pValues[i + 1] = dTemp;
                }
            }
            //执行+- //10+0*666-9
            char cPreOpera = 0;
    
            for (int i = 0; i < iOperaIndex; i++)
            {
                if (pOpera[i] == 0x2B) //+
                {
                    dTemp = pValues[i] + pValues[i + 1];
                    pValues[i] = 0;
                    pValues[i + 1] = dTemp;
                    cPreOpera = pOpera[i];
                }
                else if (pOpera[i] == 0x2D) //  -
                {
                    dTemp = pValues[i] - pValues[i + 1];
                    pValues[i] = 0;
                    pValues[i + 1] = dTemp;
                    cPreOpera = pOpera[i];
                }
                else //* /
                {
                    if (cPreOpera == 0x2B) //+
                    {
                        dTemp = pValues[i] + pValues[i + 1];
                        pValues[i] = 0;
                        pValues[i + 1] = dTemp;
                        cPreOpera = pOpera[i];
                    }
                    else if (cPreOpera == 0x2D) //  -
                    {
                        dTemp = pValues[i] - pValues[i + 1];
                        pValues[i] = 0;
                        pValues[i + 1] = dTemp;
                        cPreOpera = pOpera[i];
                    }
    
                }
            }
    
            printf("Reslut = %g\n", pValues[iValueIndex]);
            delete[] pValues;
            delete[] pOpera;
        }
        //    getchar();
    
    
        return 0;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 2月27日
  • 已采纳回答 2月19日
  • 创建了问题 2月17日

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?