用栈实现简单计算器

题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
思路解析
       先用getline函数输入一行表达式,将表达式进行解析。解析时需要用到两个栈,栈A存储运算数据,栈B用来存储运算符。从前往后逐个扫描表达式中的字符,当扫描到数字时,将数字(可能有多位)入栈A,当扫描到运算符时,需要判断一下当前运算符op优先级是否比栈B顶的优先级高,如果当前运算符优先级高,则入栈B,否则将栈B顶的运算符和栈A顶端的两个运算数据取出,进行运算,并将结果如栈A,直到当前运算符op优先级比栈顶优先级高为止,将op如栈B。扫描完后,按次序取出栈B中的一个的运算符,栈A中的两个运算数,进行计算,将结果入栈A,直到栈B中无运算符,栈A中只有一个结果C,C即为表达式结果。
代码
#include <iostream>
#include <string>
#include <stack>

using namespace std;

int lever(char op){
	if(op=='+' || op=='-'){
		return 1;
	}else{
		return 2;
	}
}

double func(double a,double b,char op){
	if(op=='+'){
		return a+b;
	}else if(op=='-'){
		return a-b;
	}else if(op=='*'){
		return a*b;
	}else{
		return a/b;
	}
}

void cal(string exp){
	stack<double> num;//存数字 
	stack<char> oper;//存运算符 
	int len = exp.length(),index_n=0,index_o=0,number=0,lev=0;
	double a,b;
	char t;
	
	for(int i=0;i<len;i++){
		if(exp[i]>='0' && exp[i]<='9'){
			number = number*10 + exp[i]-'0';
		}else if(exp[i]!=' '){
			num.push(number);
			number=0;
			//运算符比栈顶等级高则入栈,否则进行一次运算 
			if(lev<lever(exp[i])){
				oper.push(exp[i]);
				lev = lever(exp[i]);
				continue;
			}
			while(lev>=lever(exp[i])){
				t = oper.top();
				oper.pop();
				a = num.top();
				num.pop();
				b = num.top();
				num.pop();
				num.push(func(b,a,t));
				if(oper.empty()){
					break;
				}
				lev = lever(oper.top());
			}
			oper.push(exp[i]);
			lev = lever(exp[i]);
		}
	}
	num.push(number);//将最后一个数字入栈 
	
	while(!oper.empty()) {
		t = oper.top();
		oper.pop();
		a = num.top();
		num.pop();
		b = num.top();
		num.pop();
		num.push(func(b,a,t));
	}
	
	printf("%.2f\n",num.top());
}

int main(){
	string exp;
	
	while(1){
		getline(cin,exp);
		if(exp=="0"){
			break;
		}
		cal(exp);
	}
	return 0;
} 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值