zoukankan      html  css  js  c++  java
  • hdu1237 简单计算器[STL 栈]

    题目地址

    hdu1237

    题干

    代码和解释

    解本题时使用了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
    ",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('');//一开始缺少这一行,导致无法运行。因为下面需要比较opr栈顶的优先级。 
    	 
    	for(i=0;i<=strlen(str);i++){//小于等于是为了算上最后的'' 
    		if(str[i]==' '){
    			continue;
    		}
    		if(isdigit(str[i])){//如果是数字 
    			//printf("hello digit
    ");
    			sscanf(str+i,"%lf",&tmp);//sscanf可以从字符串中读取格式化输入
    			num.push(tmp);//入栈 
    			while(isdigit(str[i])){
    				i++;//跳过这个整数 
    			}
    			i--;//多加了一次,减去它 
    		}
    		else{//除了读入运算符,这里还包括最后一位'' 
    			//printf("hello other
    ");
    			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("乘法
    ");
    					t3=t2*t1;
    					//printf("t2=%.2lf,t1=%.2lf,t3=%.2lf
    ",t2,t1,t3);
    					opr.pop();
    				}
    				else if(opr.top()=='/'){
    					t3=t2/t1;//注意t2和t1的顺序
    					opr.pop(); 
    				}	
    				num.push(t3);//运算结果入栈 
    				
    				if(str[i]==''&&opr.top()==''){//字符串读完了,并且运算符也都使用完了,结束 (缺一不可)
    					//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
  • 相关阅读:
    css3 box-sizing盒模型
    数字递增组件
    设置视频水平垂直居中显示在页面上
    修改placeholder样式,兼容多个浏览器
    一款还不错的日期插件layDate
    vue-cli打包后出现 “Uncaught SyntaxError: Unexpected token <”这个错
    详谈C++虚函数表那回事(一般继承关系)
    C++多态的实现及原理详细解析
    位运算求两个数的平均值
    网页设计入门<一>
  • 原文地址:https://www.cnblogs.com/hardcoreYutian/p/11213845.html
Copyright © 2011-2022 走看看