BUPT机试(2015)解析表达式

如果机试遇到这个就肯定做不出来了,还好当年大家也都不怎么能在规定时间里面做出来╮( ̄▽ ̄")╭
慌张的很
思路需要理清楚的是,sin,cos,tan,lg,ln这些函数在后缀表达式里应该放在哪里;有括号的没括号的怎么处理。
看到网上很多之前年份的做的各种,但是没办法提交,暂且算了一下还可以叭,可能细节会出问题。做这个题就是为了打击一下自己,emmm

原题目:
第四题:解析表达式
描述:输入一个字符串形式的表达式,该表达式中包括整数,四则运算符(+、-、*、/),括号,三角函数(sin(x)、cos(x)、tan(x)),底数函数(lg(x)、ln(x)),计算该表达式的值
输入:输入一个字符串形式的表达式,保证中间及最终结果不超出double的范围
输出:表达式的值,保留6位小数
样例输入:
3
3+5
((2-1)*5-1)*6
1+cos(0)
sin(sin(1-1))
样例输出:
3.000000
8.000000
24.000000
2.000000
0.000000

#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
struct node{
	double num;
	char op;
	bool flag;//true为op,false为num; 
}temp;

double sum=0;
string s;
stack<node> ch;
queue<node> q;

void convert(){
	double num;
	for(int i=0;i<s.length();){
		if(isdigit(s[i])){//数字,这个部分只有正整数 
			num=s[i++]-'0';
			while(isdigit(s[i])){
				num=num*10+(s[i++]-'0');
			}temp.flag=false;
			temp.num=num;
			q.push(temp);
		}else if(s[i]=='('){ //左括号直接进入符号栈 
			temp.flag=true;
			temp.op=s[i++];
			ch.push(temp);
		}else if(s[i]==')'){ //右括号 
			temp=ch.top();
			while(temp.op!='('){ //直到遇到左括号全部加入后缀表达式 
				ch.pop();
				q.push(temp);
				temp=ch.top();
			}ch.pop();
			i++;
			if(ch.empty()) continue;
			temp=ch.top(); ;
			while(temp.op=='s'||temp.op=='c'||temp.op=='t'||temp.op=='g'||temp.op=='n'){//其他计算也加入后缀表达式 
				q.push(temp);
				ch.pop();
				if(ch.empty()) break;
				temp=ch.top();
			}
		}else if(s[i]=='s'||s[i]=='c'||s[i]=='t'){//其他计算符进入符号栈 
			temp.flag=true;
			temp.op=s[i];
			ch.push(temp);
			i+=3;
		}else if(s[i]=='l'){
			temp.flag=true;
			temp.op=s[i+1];
			q.push(temp);
			i+=2;
		}else{
			if((s[i]=='+'||s[i]=='-')&&!ch.empty()){
				temp=ch.top();
				while(temp.op=='*'||temp.op=='/'){//+-遇到*/需要前置 
					q.push(temp);
					ch.pop();
					temp=ch.top();
				}temp.op=s[i];
				ch.push(temp);
				i++;
			}else{//*/或空符号栈的+-直接进入符号栈 
				temp.flag=true;
				temp.op=s[i++];
				ch.push(temp);
			}
		}
	}while(!ch.empty()){//不空的符号全部加入后缀表达式 
		temp=ch.top();
		q.push(temp);
		ch.pop();
	}
}
void cal(){//计算后后缀表达式 
	while(!q.empty()){
		temp=q.front();
		if(!temp.flag){
			ch.push(temp);
		}else{
			char op=temp.op;
			temp.flag=false;
			if(op=='+'||op=='-'||op=='*'||op=='/'){
				double n2=ch.top().num;ch.pop();
				double n1=ch.top().num;ch.pop();
				if(op=='+') temp.num=n1+n2;
				else if(op=='-') temp.num=n1-n2;
				else if(op=='*') temp.num=n1*n2;
				else if(op=='/') temp.num=n1/n2;
			}else{
				double n=ch.top().num;ch.pop();
				if(op=='s') temp.num=sin(n);
				else if(op=='c') temp.num=cos(n);
				else if(op=='t') temp.num=tan(n);
				else if(op=='g') temp.num=log(n);
				else if(op=='n') temp.num=log10(n);
			}ch.push(temp);
		}q.pop();
	}
}
int main(){
	getline(cin,s);
	convert();
	cal();
	temp=ch.top();
	printf("%.6f\n",temp.num);
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_32719923/article/details/88745567