九度oj 题目1019:简单计算器 【ZJU2006考研机试题5】

题目1019:简单计算器

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:3287

解决:1211

题目描述:
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入:
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出:
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入:
1 + 2
4 + 2 * 5 - 7 / 11
0
样例输出:
3.00
13.36
来源:
2006年浙江大学计算机及软件工程研究生机试真题
答疑:
解题遇到问题?分享解题心得?讨论本题请访问: http://t.jobdu.com/thread-7743-1-1.html
本题方法编写计算器做到升级版,跳过任意多个前中后的空格~~

写百行以上的程序,更好的锻炼自己的代码能力~  任重而道远啊~~

/*  
	1.符号栈为空 或优先级高于栈顶 则进 符号栈。是高于啊!!!
	2.当while操作符出栈运算完后,当前运算符优先级高于栈顶了,故要运算符需入栈。。别漏了。。。。
*/	
#include<stdio.h>
#include<stack>
using namespace std;
stack<double> num;
stack<int> op;
char r[210];
int pri[5][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
};
bool isDigit(char c)
{
	if(c>='0'&&c<='9')
		return true;
	else
		return false;
}
bool isOperator(char d)
{
	if(d=='+'||d=='-')
		return true;
	else if(d=='*'||d=='/')
		return true;
	else
		return false;
}
int str2Op(char e)
{
	if(e=='+') return 1;
	if(e=='-') return 2;
	if(e=='*') return 3;
	if(e=='/') return 4;
	return NULL;
}
void getCh(bool &tmpO,int &tmpN,int &tmpId)  //要么 获得一个操作数 要么 获得一个操作符
{
	if(tmpId==0&&op.empty()==true){//第一个必然为数字,此处只是为了方便运算而加额外字符
		tmpO=true;tmpN=0; return;
	}
	if(r[tmpId]==0){
		tmpO=true;tmpN=0; return;
	}

	while(true){  //是为了跳过空格
		if(r[tmpId]==' '){
			tmpId++;continue;
		}
		else if(isOperator(r[tmpId])){  //获得一个操作符
			tmpO=true;tmpN=str2Op(r[tmpId]);tmpId++;break;
		}else{
			tmpN=0;
			while(isDigit(r[tmpId])){   //获得一个操作数
				tmpO=false;tmpN=tmpN*10+r[tmpId]-'0'; tmpId++;				
			}
//			printf("当前数字是:%d ",tmpN);
//			printf("\n");
			break;
		}
	}

}
int main()
{
	//freopen("G:\\in.txt","r",stdin);
	while(gets(r)){          //每次读一行,直到文件尾。
		if(r[0]=='0'&&r[1]==0) break;  //gets()遇到换行就截止,换行对应存的是0 ;
		while(!num.empty()) num.pop();
		while(!op.empty()) op.pop();
		int id=0;			  //标记当前读到的位置。
		bool isOp;		 //作为引用,以在函数中修改
		int ch;             //作为引用,以在函数中修改
		while(true){
			getCh(isOp,ch,id); //获取当前id开始的一个操作数 OR 一个操作符,跳过空格。
			if(isOp==false){  //若为数字直接进数字栈
				num.push((double)ch);
//				printf("当前数字是:%.2lf ",num.top());
//				printf("\n");
			}
			else if(op.empty()==true||pri[ch][op.top()]==1){ //符号栈为空 或优先级高于栈顶 则进 符号栈
				op.push(ch);
//				printf("当前数字是:%d ",op.top());
//				printf("\n");
			}
			else{
				while(pri[ch][op.top()]==0){
//					printf("当前数字是:%d ",op.top());
//					printf("\n");
					double tmp1=num.top();
					num.pop();
					double tmp2=num.top();
					num.pop();
					int nowOp=op.top();
					op.pop();
					double nowNum;
					if(nowOp==1)
						nowNum=tmp2+tmp1;
					if(nowOp==2)
						nowNum=tmp2-tmp1;
					if(nowOp==3)
						nowNum=tmp2*tmp1;
					if(nowOp==4)
						nowNum=tmp2/tmp1;
					num.push(nowNum); //运算完后把该步运算结果入数字栈。
				}
				op.push(ch); //上个while运算完后当前运算符优先级高于栈顶了,故要运算符入栈。。。。。别漏了。。。。
			}
			if(op.size()==2&&op.top()==0) break;  //该循环跳出的条件。
		}
		printf("%.2lf\n",num.top());
	}
	return 0;
}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值