表达式求值(南阳理工—35)

表达式求值

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 4
             描述:
ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
输入
第一行输入一个整数n,共有n组测试数据(n<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
数据保证除数不会为0
输出
每组都输出该组运算式的运算结果,输出结果保留两位小数。
样例输入
2
1.000+2/4=
((1+2)*5+1)/4=
样例输出
1.50
4.00


(一)题目链接:南阳理工23

解题思路:

中缀表达式转后缀表达式:首先将加、减、乘、除运算符进行优先级划分,括号为最高优先级,之后为乘除、再为加减,等号为最低优先级,方便利用栈将运算符利用特定规则进行转换。之后遍历字符串,如果为数字字符或者小数点运算符,则将其添加为后缀表达式,后加一个空格,方便之后sstreamstring流输入,如果是运算符字符,则将按照规则进行进栈或者出栈操作,进栈则将运算符压入栈顶,出栈操作则将运算符添加入后缀表达式,后加空格。


运算符规则:首先栈为空时将运算符进栈,之后遇到运算符时,将其与栈顶运算符比较,如果当前运算符优先级高于栈顶运算符,则将当前元素进栈;如果当前元素优先级低于栈顶元素,则不断出栈,直到栈中出现更低优先级或者栈为空,最后将该运算符进栈。特别的:如果是括号运算符,遇左括号,则进栈,如果遇到右括号,则出栈 栈中左括号及左括号以上所有的运算符,且右括号不进栈。


后缀表达式求值:通过以上步骤,可以得到后缀表达式字符串,且每个数字字符串和运算符字符用空格进行了分割,方便我们用streamstring进行操作,然后遍历后缀字符串,对于数字字符串,我们用 atof( )函数可将其转换为数字,同时进栈,如果遇到运算符,取栈顶元素进行相应运算,最后再将结果进栈,最后遇到等号运算符结束,当前栈中唯一栈顶元素即为表达式的值。

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int Judge(char ch){
	//运算符进行优先级划分 
	if(ch == '+') return 1;
	if(ch == '-') return 1;
	if(ch == '*') return 2;
	if(ch == '/') return 2;
	if(ch == '(') return 0;
	if(ch == ')') return 0;
}
int main (void){
	string str;
	string s;
	int count ;
	cin>>count;
	while(count--){
		int i=0 ;
		str.clear();
		s.clear() ;
		cin>>str;
		stackmid; //字符串栈 ,用于中缀表达式转后缀表达式 
		stackans;//数字栈 ,用于后缀表达式求值 
		while(str[i] != '=')
		{
			if(str[i] == '('){//判断,左括号进栈 
				mid.push(str[i]);
				i++;
			}
			else if( str[i] == ')')//遇右括号则将左括号及左括号以上标识符出栈 
			{
				while(mid.top()!='(')
				{
					s = s + mid.top() ;
					s += ' ';
					mid.pop() ;
				}
				mid.pop() ;
				i++;
			}
			else if(isdigit(str[i]))//数字或小数点则直接转入后缀表达式 
			{
				while(str[i]<='9'&&str[i]>='0' || str[i] =='.')
				{
					s = s + str[i];
					i++;
				}
				s += ' ';
			}
			else if(str[i] == '+'||str[i] == '-'||str[i] == '*'||str[i] == '/'){
				while(!mid.empty() && Judge(mid.top()) >= Judge(str[i])){
				//当前运算标识符优先级低于栈顶元素,进行出栈操作 
					s = s + mid.top();
					s = s + ' ';
					mid.pop();
				}
				mid.push(str[i]);//将当前运算符进栈 
				i++;
				
			}	
		}
		while(!mid.empty())//将最后剩余运算符出栈 
		{
			s = s + mid.top() ;
			s = s + ' ';
			mid.pop() ;
		}
		string temp;
		stringstream ss(s);
		char a[1000];
		double num;
		while(ss>>temp)
		{
			if( isdigit(temp[0]) ){
				for(i=0;i



你可能感兴趣的:(数据结构)