夕拾算法进阶篇:6)简单计算器(stack)

题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。


输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。


输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。


样例输入
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0
样例输出

12178.21


很明显是栈的简单应用,大致思路如下:

(1)依次扫描字符串,如是操作数则直接入栈,如是操作符,则进入(2)

(2)若操作符栈为空则直接入栈,否则比较栈顶的操作符与当前的操作符的优先级。若栈顶的优先级较低,操作符直接入栈,否则从操作数栈中弹出2个操作数,从操作符栈中弹出一个操作符进行运算,并把结果入栈。

这里只需注意细节问题,比如回退下标和处理最后一个操作数。具体可参看代码中的注释

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;

bool isNumber(char v){
	return v<='9' && v>='0';
}

bool isOperationChar(char v){
	return v=='+' || v=='-' || v=='*' || v=='/'; 
}

//+-的优先级为0,*/为1
bool getCharPriority(char v){
	if(v=='-'||v=='+') return 0;
	return 1;
}

//计算2个操作数 
double operation(double num1,double num2,char op){
	switch(op){
		case '+': return num1+num2;
		case '-': return num1-num2;
		case '*': return num1*num2;
		case '/': return num1/num2;
	}
}

//从操作数栈中取2个数,从运算符中取符号进行运算并入栈 
void calculate(stack<char> &st_char,stack<double> &st_number){
	double num2=st_number.top(); st_number.pop();
	double num1=st_number.top(); st_number.pop();
	char op=st_char.top(); st_char.pop();
	double r=operation(num1,num2,op);
	st_number.push(r);
}


int main(){
	stack<char> st_char; //运算符栈 
	stack<double> st_number;//操作数栈 
	string value;
	int i,j,len;
	while(getline(cin,value),value!="0"){
		double sum=0;
		len=value.length();
		for(i=0;i<len;i++){
			if(value[i]==' ')
				continue;  //跳过空格
			if(isNumber(value[i])){
				sum=sum*10+value[i]-'0'; //累加操作数
				if(i>=len-1){ //最后一个操作数 
					st_number.push(sum);
					while(!st_char.empty()){
						calculate(st_char,st_number);
					}
				}
			}else if(isOperationChar(value[i])){	
				if(sum!=-1) //非回退 
					st_number.push(sum); //操作数入栈
				sum=0; //操作数累加重置 
				if(st_char.empty()){ //符号栈为空,直接入栈
					st_char.push(value[i]);
				}else{ //不为空,比较当前符号和栈顶符号的优先级
					char op=st_char.top();
					if(getCharPriority(op)>=getCharPriority(value[i])){
						//若栈顶符号的优先级大于等于当前的符号,则计算后把结果入栈
						calculate(st_char,st_number);
						i--; //i回退1 
						sum=-1; //sum=-1 为回退的标志 
					}else{
						st_char.push(value[i]);
					}
				}
			}
		}
		printf("%.2lf\n",st_number.top()); //最后在操作数栈里面的就是运算结果 
	}
	return 0;
} 


题目来源: http://codeup.cn/problem.php?cid=100000602&pid=0


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值