表达式求值 自己实现的坑

表达式求值

题目描述:

对于一个不存在括号的表达式进行计算

输入:

存在多种数据,每组数据一行,表达式中数字后存在空格

输出:

输出结果

样例输入:

6 / 2 + 3 + 3 * 4
样例输出:

18
wc,这个题,自己实现有很多很多坑

1.运算符优先级,自己的优先级小于自己!矩阵0多1少

2. 如果表达式中有空格,一定使用gets读取表达式!!

3.注意可能会需要使用double栈存储数字防止小数

如果表达式中有括号,左括号直接强制入栈!

右括号优先级比加减乘除都低。

1.左括号的优先级仅高于#;

2.但是遇见左括号时,不用和OPTR栈顶元素进行优先级比较,直接强制进OPTR栈;

3.遇到右括号,退OVS栈两次,退OPTR栈一次,进行相应的运算操作,将计算结果压入OVS栈,直到OPTR栈顶元素是左括号为止,并将左括号弹出OPTR栈;

#include<iostream>
#include<stack>
using namespace std;
stack<int> op;
stack<double> in;

char str[220];
//运算符优先级 0+-*/ 其中0是自定义的优先级最低的运算符 
//值为1代表优先级高 
int mat[][5]={
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,0,0,
1,1,1,0,0

};
//reto代表是运算符还是数字 
//retn代表返回值 :运算符编号或者数字
//i是字符串标号 
void getOp(bool &reto,int &retn,int &i)
{
    //人为补充表达式首尾的两个低级运算符0 
    if(i==0&&op.empty()==true)
    {
        reto=true;
        retn=0;
        return;
    } 
    if(str[i]==0)
    {
        reto=true;
        retn=0;
        return;
    }
    if(str[i]>='0'&&str[i]<='9')
    {
        reto=false;
        
    }
    else
    {
        reto=true;
        if(str[i]=='+')
        {
            retn=1;
            
        }
            if(str[i]=='-')
        {
            retn=2;
            
        }
            if(str[i]=='*')
        {
            retn=3;
            
        }
            if(str[i]=='/')
        {
            retn=4;
            
        }
        i+=2;
        //i向后移动 跨过当前运算符和空格 
        return;
    }
    
    //截取完整数字
    retn=0;
    for(;str[i]!=0&&str[i]!=' ';i++)
    {
        retn*=10;
        retn+=str[i]-'0';
    } 
    //如果题目说明数字后没空格,下面跳过空格的代码注释掉即可
    if(str[i]==' ')
    {
        i++;
    }
    return;    
}
int main()
{
    while(gets(str))
    {
        if(str[0]=='0'&&str[1]==0)
        {
            break;
        }
        //重置清零操作 
        bool retop;
        int retnum;
        int idx=0;
        while(!op.empty())
        {
            op.pop();
        }
        while(!in.empty())
        {
            in.pop();
        }
        //开始处理 
        while(true)
        {
            getOp(retop,retnum,idx);
            if(retop==true)
            {
            
                if(op.empty()==true||mat[retnum][op.top()]==1)
                {
                    op.push(retnum);
                }
                else
                {
                    double n1,n2;
                    int o;
                    double result;
                    while(mat[retnum][op.top()]==0)
                    {
                        o=op.top();
                        op.pop();
                        n1=in.top();
                        in.pop();
                        n2=in.top();
                        in.pop();
                        if(o==1)
                        {
                            result=n1+n2;
                        }
                        else if(o==2)
                        {
                            result=n1-n2;
                        }
                        else if(o==3)
                        {
                            result=n1*n2;
                        }
                        else if(o==4)
                        {
                            result=n1/n2;
                        }
                        in.push(result);
                        
                    
                    }
                    op.push(retnum);
                }
                                
            }
            else
            {
            in.push(retnum);            
            }
        
         if(op.size()==2&&op.top()==0)
         {
             break;
         }
        }
        printf("%.2f\n",in.top());
        
    }
    
    
    
    
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值