基于栈的中缀算术表达式求值

基于栈的中缀算术表达式求值

描述

输入一个中缀算术表达式,求解表达式的值。运算符包括+、-、*、/、(、)、=,参加运算的数为double类型且为正数。(要求:直接针对中缀算术表达式进行计算,不能转换为后缀或前缀表达式再进行计算,只考虑二元运算即可。)

输入

多组数据,每组数据一行,对应一个算术表达式,每个表达式均以“=”结尾。当表达式只有一个“=”时,输入结束。参加运算的数为double类型。

输出

对于每组数据输出一行,为表达式的运算结果。输出保留两位小数。

输入样例 1 

2+2=
20*(4.5-3)=
=

输出样例 1

4.00
30.00
#include <iostream>
 
#include<cmath>
 
#include <iomanip>
 
#define MAXSIZE 1000
 
using namespace std;
 
char op[7] = { '+', '-', '*', '/', '(', ')', '=' };
 
 
 
typedef struct 
 
{
 
	char *base;
 
	char *top;
 
	int stacksize;
 
	
 
}SqStackOPTR;
 
 
 
typedef struct 
 
{
 
	double *base;
 
	double *top;
 
	int stacksize;
 
	
 
}SqStackOPND;
 
 
 
int InitStack(SqStackOPTR &S)
 
{
 
 	S.base=new char [MAXSIZE];
 
	if(!S.base) return 0;
 
 	S.top=S.base;
 
 	S.stacksize=MAXSIZE;
 
 	return 1;
 
}
 
 
 
int InitStack(SqStackOPND &S)
 
{
 
 	S.base=new double [MAXSIZE];
 
	if(!S.base) return 0;
 
 	S.top=S.base;
 
 	S.stacksize=MAXSIZE;
 
 	return 1;
 
}
 
 
 
int Push(SqStackOPTR &S,char e)
 
{
 
	if(S.top-S.base==S.stacksize) return 0;	
 
	*S.top=e;
 
	S.top++;
 
	return 1;
 
}
 
 
 
int Push(SqStackOPND &S,double e)
 
{
 
	if(S.top-S.base==S.stacksize) return 0;	
 
	*S.top=e;
 
	S.top++;
 
	return 1;
 
}
 
 
 
 
 
double GetTop(SqStackOPND S)
 
{
 
	if(S.top!=S.base)
 
		return *(S.top-1);
 
}
 
 
 
char GetTop(SqStackOPTR S)
 
{
 
	if(S.top!=S.base)
 
		return *(S.top-1);
 
}
 
 
 
int Pop(SqStackOPTR &S,char &e)
 
{
 
	if(S.top==S.base) return 0;
 
	S.top--;
 
	e=*S.top;
 
	return 1;
 
}
 
 
 
int Pop(SqStackOPND &S,double &e)
 
{
 
	if(S.top==S.base)	return 0;
 
	S.top--;
 
	e=*S.top;
 
	return 1;
 
}
 
 
 
int In(char ch) {//判断ch是否为运算符
 
	for (int i = 0; i < 7; i++) {
 
		if (ch == op[i]) {
 
			return 1;
 
		}
 
	}
 
	return 0;
 
}
 
char Precede(char c1, char c2)
 
{
 
	if((c1=='('&&c2==')')||(c1=='='&&c2=='=') )return '=';
 
	else
 
	if(((c1=='+'||c1=='-'||c1=='*'||c1=='/'||c1==')') && (c2=='+'||c2=='-'||c2==')'||c2=='='))||((c1=='*'||c1=='/'||c1==')')&&(c2=='*'||c2=='/')))return '>';
 
	else
 
	if(((c1=='('||c1=='=')&&c2!=')'&&c2!='=')|| ((c1=='+'||c1=='-')&&(c2=='*'||c2=='/'))||c1=='('||c2=='(') return '<';
 
	else 
 
	cout<<c1<<" "<<c2<<"没有输出"<<endl; 
 
}
 
double Operate(double first, char theta, double second) {//计算两数运算结果
 
	switch (theta) {
 
	case '+':
 
		return first + second;
 
	case '-':
 
		return first - second;
 
	case '*':
 
		return first * second;
 
	case '/':
 
		return first / second;
 
	}
 
	return 0;
 
}
 
 
 
 
 
double EvaluateExpression(char ch) {//算术表达式求值的算符优先算法,设OPTR和OPND分别为运算符栈和操作数栈
 
	
 
	SqStackOPTR OPTR;
 
	SqStackOPND OPND;
 
	
 
	char theta;double a, b;char x, top;
 
	InitStack(OPTR);
 
	InitStack(OPND); 
 
	Push(OPTR, '=');
 
	//cout<<"此时ch为:"<<ch<<endl;
 
	while (ch != '=' || (GetTop(OPTR) != '=')) //表达式没有扫描完毕或OPTR的栈顶元素不为“=”
 
	{
 
		char sign='+';
 
		if(ch=='-')
 
		{
 
			sign=ch;
 
		}
 
		if(!In(ch))//不是运算符则解析数字字符串然后进操作数栈
 
		{
 
			double m=0,n=0;
 
			while(ch!='.'&&ch>='0'&&ch<='9')
 
			{//解析整数部分
 
				m=m*10+(ch-48);
 
				cin >> ch;
 
			}
 
			if(ch=='.')//解析小数部分
 
				cin >> ch;
 
			int k=1;
 
			while(ch>='0'&&ch<='9')
 
			{
 
				n=n+(ch-48)*pow(10.0,-k);
 
				k++;
 
				cin>>ch;
 
			}
 
		//	cout<<"此时ch为:"<<ch<<endl;
 
		//	cout<<"数解析为:"<<m+n<<endl;
 
			if(sign=='-')
 
			{
 
				Push(OPND,-(m+n));
 
		//		cout<<"进栈:" <<-(m+n)<<endl; 
 
			}	
 
			else
 
			{
 
				Push(OPND,m+n);
 
		//		cout<<"进栈:" <<m+n<<endl; 
 
			}
 
		//	cout<<"此时ch为:"<<ch<<endl;
 
		//	cout<<"此时栈顶元素为"<<GetTop(OPTR)<<endl;
 
		}//while 解析第一个数,整合整数部分和小数部分并将其压入栈 
 
		else//如果不是数,则比较运算符优先级 
 
			switch (Precede(GetTop(OPTR), ch)) //比较OPTR的栈顶元素和ch的优先级
 
			{
 
			case '<'://还暂时不用对数栈运算 
 
			//	cout<<GetTop(OPTR)<<"<"<<ch<<endl;
 
				Push(OPTR, ch);
 
			//	cout<<"进栈:" <<ch<<endl;
 
				cin >> ch; //当前字符ch压入OPTR栈,读入下一字符ch
 
			//	cout<<"此时ch为:"<<ch<<endl;
 
				break;
 
			case '>'://弹出该运算符并弹出两个数,进行运算 
 
			//	cout<<GetTop(OPTR)<<">"<<ch<<endl;
 
				Pop(OPTR, theta); //弹出OPTR栈顶的运算符
 
				Pop(OPND, b);
 
				Pop(OPND, a); //弹出OPND栈顶的两个运算数
 
			//	cout<<"出栈:" <<b<<theta<<a<<endl;
 
				Push(OPND, Operate(a, theta, b)); //将运算结果压入OPND栈
 
				//cout<<a<<theta<<b<<":"<<Operate(a, theta, b)<<endl;
 
				//cout<<"进栈:" <<Operate(a, theta, b)<<endl;
 
				break;
 
			case '=': //OPTR的栈顶元素是“(”且ch是“)”,括号内容已经运算完毕,现在去括号 
 
				//cout<<GetTop(OPTR)<<"="<<ch<<endl;
 
				Pop(OPTR, x);
 
				//cout<<"出栈:" <<x<<endl;
 
				cin >> ch; //弹出OPTR栈顶的“(”,读入下一字符ch
 
				//cout<<"此时ch为:"<<ch<<endl;
 
				break;
 
			} //switch
 
	} //while
 
	//cout<<"GetTop(OPND);"<<GetTop(OPND)<<endl;
 
	return GetTop(OPND); //OPND栈顶元素即为表达式求值结果
 
}
 
 
 
 
 
int main()
 
{
 
 
 
	while (1)
 
	{			
 
				char ch;
 
				cin >> ch;
 
				//cout << "请输入要计算的表达式" << endl;
 
				if(ch=='=')break;
 
				double res = EvaluateExpression(ch);//算法3.22 表达式求值
 
				cout <<setiosflags(ios::fixed)<<setprecision(2)<< res <<endl;
 
	}
 
	return 0;
 
}

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值