蓝桥杯 算法训练 表达式计算

问题描述
  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
  输入一行,包含一个表达式。
输出格式
  输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定

  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。




#include <iostream>
#include<cstring>
#include<cstdio>
#include<stack>
using namespace std;
stack<double>sd;//数字栈
stack<char>sc;//字符栈
char map[8][8] = {
	
	{' ','+','-','*','/','(',')','='},
	
	{'+','>','>','<','<','<','>','>'},
	
	{'-','>','>','<','<','<','>','>'},
	
	{'*','>','>','>','>','<','>','>'},
	
	{'/','>','>','>','>','<','>','>'},
	
	{'(','<','<','<','<','<','=',' '},
	
	{')','>','>','>','>',' ','>','>'},
	
	{'=','<','<','<','<','<',' ','='}
	
	};  //优先级表格
bool isOper(char ch) {//判断是否是运算符 
	char str[] = "+-*/()=";
	for(int i=0;str[i];i++)
	if(ch==str[i])
	return false;
	return true;
}
char check(char ch1, char ch2){//比较运算符优先级 
	int i,j;
	for(i=0;i<8;i++){
		if(map[0][i]==ch1)
		break;
	}
	for(j=0;j<8;j++){
		if(map[j][0]==ch2)
		break;
	}
	return map[j][i];
}

double Calu(double a, double b, char c){//计算表达式的值 
	switch(c){
		case '+':return a+b;
		break;
		case '-':return a-b;
		break;
		case '*':return a*b;
		break;
		case '/':return a/b;
		break;
	}
}

void Calulate(char *ch, double *result){
	sc.push('=');
	int i=0,j;
	int sum=0;
	int doc=0;
	while(sc.top()!='='||ch[i]!='='){//表达式遇到等号退出循环
	
		if(ch[i]>='0'&&ch[i]<='9'||ch[i]=='.')//数字就进数字栈 
		{	sum=0;
			doc=0;
			if(ch[i]>='0'&&ch[i]<='9')
			sum = ch[i]-'0';
			j=i+1;
			while(isOper(ch[j]))//循环到一个数字串的结束,也就算遇到运算符停止 
			{
				if(ch[j]=='.'){
					doc=10;
					j++;
					continue;
				}
				if(!doc){///整数 
					sum=sum*10+ch[j]-'0';
				}
				else{//小数 
					sum=sum+1.0*(ch[j]-'0')/doc;
					doc*=10;
				}
				j++;
			}
			i=j;//把i移到j当前所在的位置
			sd.push(sum) ;//压入数字栈
	}
	
	else{//如果是运算符 
		switch(check(ch[i],sc.top()))///判断栈顶运算符,和 当前运算符优先级
		{
			case '<':
				sc.push(ch[i++]);
				break;
			case '=':
				sc.pop();//遇到括号右括号,把栈顶元素弹出,直到左括号(左括号也弹出) 
				i++;
				break;
			case '>':
				char x = sc.top();//获取栈顶元素
				sc.pop(); //弹出栈顶元素
				double b = sd.top();
				sd.pop();
				double a = sd.top();
				sd.pop();
				//计算值
				*result = Calu(a,b,x);
				sd.push(*result);
				break;
		}
	}
}
}

int main(){
	double s; 
	char ch[1010]={0};
	scanf("%s", ch);
	ch[strlen(ch)]='=';
	Calulate(ch, &s);
	printf("%.0lf\n", s);

	return 0;
}
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值