hdu1237 简单计算器[STL 栈]

题目地址

hdu1237

题干

1559979-20190719161444354-126354776.png

代码和解释

解本题时使用了STL 栈,要记得使用#include<stack>
解本题时使用了isdigit()函数,要使用#include<ctype.h>

逆波兰表达式:

1.又叫后缀表达式。我们平时使用的叫做中缀表达式,可以由下图对比理解。
后缀
2.栈的操作:
如果当前字符为变量或者为数字,则压栈,
如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈
最后当扫描完后,栈里的就是结果。

本题方法——算符优先法:

栈的操作:
从左向右扫描,遇到操作数压入操作数栈。
遇到运算符,先与运算符栈顶运算符比较优先级,(我的代码里使用pri函数定义优先级)
若栈顶运算符的优先级高(或相等),则栈顶运算符出栈并执行运算。
否则将当前运算符入栈,直至整个表达式求值完毕。

这里是c++代码。

#include<iostream>
#include<string.h>
#include<stack>
#include<ctype.h>
using namespace std;
int pri(char c);
char str[250];
double cal();   
int main()
{
    while(gets(str)!=NULL && strcmp(str,"0")!=0){
        printf("%.2lf\n",cal()); 
    } 
    return 0;
}

int pri(char c){
    if(c=='*'||c=='/'){
        return 2;
    }
    else if(c=='+'||c=='-'){
        return 1;
    }
    else return 0;//这里处理了'/0'的情况 
}

double cal(){
    double tmp;
    int i;
    double t1,t2,t3;
    stack<double> num;//存操作数,因为最终结果为浮点数,所以设为double 
    stack<char> opr;//存运算符
    opr.push('\0');//一开始缺少这一行,导致无法运行。因为下面需要比较opr栈顶的优先级。 
     
    for(i=0;i<=strlen(str);i++){//小于等于是为了算上最后的'\0' 
        if(str[i]==' '){
            continue;
        }
        if(isdigit(str[i])){//如果是数字 
            //printf("hello digit\n");
            sscanf(str+i,"%lf",&tmp);//sscanf可以从字符串中读取格式化输入
            num.push(tmp);//入栈 
            while(isdigit(str[i])){
                i++;//跳过这个整数 
            }
            i--;//多加了一次,减去它 
        }
        else{//除了读入运算符,这里还包括最后一位'\0' 
            //printf("hello other\n");
            while(pri(str[i])<=pri(opr.top())){
                t1=num.top();
                num.pop();
                t2=num.top();
                num.pop();
                if(opr.top()=='+'){
                    t3=t2+t1;
                    opr.pop();
                }
                else if(opr.top()=='-'){
                    t3=t2-t1;//注意t2和t1的顺序
                    opr.pop(); 
                }
                else if(opr.top()=='*'){
                    //printf("乘法\n");
                    t3=t2*t1;
                    //printf("t2=%.2lf,t1=%.2lf,t3=%.2lf\n",t2,t1,t3);
                    opr.pop();
                }
                else if(opr.top()=='/'){
                    t3=t2/t1;//注意t2和t1的顺序
                    opr.pop(); 
                }   
                num.push(t3);//运算结果入栈 
                
                if(str[i]=='\0'&&opr.top()=='\0'){//字符串读完了,并且运算符也都使用完了,结束 (缺一不可)
                    //printf("%c",opr.top());
                    return num.top();//返回计算的最终结果 
                } 

            }
            opr.push(str[i]);
        }
    }

}

本题要注意输入数据的方法:
while(gets(str)!=NULL && strcmp(str,"0")!=0)
解本题时出现了很多微观的问题,在代码的注释中也有提及,一点点地改进,最终提交oj一次ac很爽( ̄▽ ̄)

参考

HDU1237简单计算器-中缀表达式-后缀表达式

例子说明
stack<Type> s;定义栈,Type为数据类型,如int,float,char等。
s.push(item);把item放到栈顶
s.top();返回栈顶的元素,但不会删除
s.pop();删除栈顶的元素,但不会返回
s.size();返回栈中元素的个数
s.empty();检查栈是否为空,如果为空返回true,否则返回false

转载于:https://www.cnblogs.com/hardcoreYutian/p/11213845.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值