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\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
posted @ 2019-07-19 16:42  平静的雨田  阅读(551)  评论(1编辑  收藏  举报