【九度】题目1019:简单计算器

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:8387

解决:3065

题目描述:
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入:
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出:
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入:
1 + 2
4 + 2 * 5 - 7 / 11
0
样例输出:
3.00
13.36
#include "stdafx.h"
#include <stack>
using namespace std;
char str[220];
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,
};
stack<int> op;
stack<double> in;

void getOp(bool &reto,int &retn,int &i){
	//获得表达式中下个元素函数,若函数运行结束的时候,引用变量reto为true,表示元素为一个运算符,编号保存在retn中。
	//否则,为数字,值保存在retn中。
	if(i==0&&op.empty()==true){//第一个字符,人为添加为0的标记字符。注意,第一次执行后,该标记字符入栈了,op不为空了,后面不会再执行了。
                                   //该标记字符用于循环的退出,由于是标记字符强行添加的,所以不用i++
	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]!=' '&&str[i]!=0;i++){//读出连续的数字,并使i的下标前进
	retn*=10;
	retn+=str[i]-'0';//减去0的ascii码,得到数字。
	}
	if(str[i]==' ')i++;return;//i递增+1;
}

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) in.push((double)retnum);//数字直接压入数字栈k
			else

			{
				double tmp;
			if(op.empty()==true||mat[retnum][op.top()]==1) op.push(retnum);//满足入栈条件,压入op栈
			else
			{//不满足,取栈顶元素与数字栈的两个数字运算,将值压入数字栈中;
				while (mat[retnum][op.top()]==0)
				{
					int ret=op.top();
					op.pop();
					double a=in.top();in.pop();
					double b=in.top();in.pop();
					if(ret==1) tmp=a+b;
					if(ret==2) tmp=b-a;
					if(ret==3) tmp=a*b;
					if(ret==4) tmp=b/a;
					in.push(tmp);
				}
				op.push(retnum);
			}
			}
			if(op.size()==2&&op.top()==0) break;
		}
		printf("%.2lf\n",in.top());
	
	}
	return 0;
}


引用的作用是给一个变量起一个别名,例如有一个变量a,想给他起一个别名b,可以写成:int a; int &b=a; 

 这样声明后,代表a和b就是同一变量单元,而&不是代表取地址符号,而是引用声明符,说明定义了b可并没有为它另开辟内存单元,b和a就是同一变量。


在声明一个引用型变量时,必须同时为它初始化,即声明它代表哪一个变量,在声明一个变量的引用后,在本函数执行期间,该引用一直与其代表的变量相联系,不能再作为其他变量的别名。下面举个不对的例子:
int a;
int b;
int &c=a;int &c=b;
这样企图让C既是A又是B的别名是不对的。


引用的出现主要是把它作为函数参数,以扩充函数传递数据的功能。用传递变量别名的方法实现函数传递数据。下面举个例子:
#include "iostream.h"
void swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
void main()
{
int i=3,j=5;
swap(i,j);
cout<<"i=";
cout<<i;
cout<<"j=";
cout<<j;
}



ps:上交10年的机试题没有要求有空格,那么只需要修改

void getOp(bool &reto,int &retn,int &i){
	//获得表达式中下个元素函数,若函数运行结束的时候,引用变量reto为true,表示元素为一个运算符,编号保存在retn中。
	//否则,为数字,值保存在retn中。
	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++;//i变为递增1
		return;}

	retn=0;//计算数字
	for(;str[i]>='1 '&&str[i]!=0;i++){//读出连续的数字,并使i的下标前进 判断语句为>='1' 运算字符的asic码小于数字的
	retn*=10;
	retn+=str[i]-'0';//减去0的ascii码,得到数字。
	}
	if(str[i]==' ')i++;return;//i递增+1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值