C++——运用栈实现表达式计算

实验要求:

运用栈的操作实现基本表达式求值

代码如下:

#include <iostream>
#include <string>
#include <cmath>
using namespace std;

//定义优先级: +,- ,* ,/ ,(,),#
//第一维表示栈内 
 char operate[7]={'+','-','*','/','(',')','#'};
 char prior[7][7] = {
 	{'>','>','<','<','<','>','>'}
	,{'>','>','<','<','<','>','>'}
	,{'>','>','>','>','<','>','>'}
	,{'>','>','>','>','<','>','>'}
	,{'<','<','<','<','<','=',' '}
	,{'>','>','>','>',' ','>','>'}
	,{'<','<','<','<','<',' ','!'}
 };
//顺序栈 
#define MAXSIZE 100
#define ERROR  0 
#define OK 	   1
typedef double ElemTypeDouble;
typedef char ElemTypeChar;

//数字栈的结构
typedef struct{
	ElemTypeDouble elem[MAXSIZE];
	int top;
	int stackSize;
}OPND;
//运算符栈的结构
typedef struct{
	ElemTypeChar elem[MAXSIZE];
	int top;
	int stackSize;
}OPTR;
//初始化栈
 int initStack(OPND &S){
 	S.top = 0;
 	S.stackSize = MAXSIZE;
 	return OK;
 }

 int initStack(OPTR &S){
 	S.top = 0;
 	S.stackSize = MAXSIZE;
 	return OK;
 }
//压栈
 int Push(OPND &S,ElemTypeDouble e){
 	if(S.top >= S.stackSize) return ERROR;
 	S.elem[S.top++] = e;
 	return OK;
 }
 
 int Push(OPTR &S,ElemTypeChar e){
 	if(S.top >= S.stackSize) return ERROR;
 	S.elem[S.top++] = e;
 	return OK;
 }
//获取栈顶元素
 int getTop(OPND &S,ElemTypeDouble &e){
 	if(S.top == 0) return ERROR;
 	e = S.elem[S.top-1];
 	return OK;
 }
 
 int getTop(OPTR &S,ElemTypeChar &e){
 	if(S.top == 0) return ERROR;
 	e = S.elem[S.top-1];
 	return OK;
 }
//出栈
 int Pop(OPND &S,ElemTypeDouble &e){
 	if(S.top ==0) return ERROR;
 	e = S.elem[S.top-1];
 	S.top--;
 	return OK;
 }
 
 int Pop(OPTR &S,ElemTypeChar &e){
  	if(S.top ==0) return ERROR;
 	e = S.elem[S.top-1];
 	S.top--;
 	return OK;	
 }

 //获取表达式中的一个数字
 double ex1(string str,int i,int &j){	 
 	int num = 0;
	int counter = 0; 
	while(str[i]>='0'&&str[i]<='9'||str[i]=='.'){	
		if(str[i]=='.') counter = -1;
		if(counter ==1){
			num = num*10+str[i]-'0';
			counter = 1;
		}else	if(counter ==0){
			num = str[i]-'0';
			counter++;
		} else{
			double t = str[i]-'0';
			num = num+t*pow(10,counter);
			counter --;
		}
			i++;
	}
	j = i; 
	return num;
 }
 //计算 
 double count(char ch,ElemTypeDouble eL,ElemTypeDouble eR){	
	switch(ch){
		case '+':return eL+eR; break;
		case '-':return eL-eR; break;
		case '*':return eL*eR; break;
		case '/':if(eR==0)return 0;
				else return eL/eR; break;
		default: return 0; break;
	}	 
 }
  
//获取字符对应下标
 int getIndex(char ch){
 	for(int i =0;i<7;i++){
 		if(ch == operate[i])
 		return i; 
 	}return ERROR; 
}
//判断字符是否为运算符
 int IsOperate(char ch){
 	for(int j =0;j<7;j++){
 		if(ch == operate[j])return OK;
	 } 
	 return ERROR;
 }
//表达式求值
  int EvalutionExpression(string str,ElemTypeDouble &result){
  	 int i;
   	 ElemTypeChar ch;
   	 ElemTypeDouble eR,eL; 
  	 int m,n;

  	 OPTR S1;
  	 OPND S2;		//S1:运算符,S2:操作数 
  	 initStack(S1);		//初始化 
  	 initStack(S2);
  	 
  	 Push(S1,'#');
	 
  	 for(i=0;str[i]!='\0';i++) ;
	 str[i] = '#';
	 str[i+1] = '\0';
	 i=0;
	 getTop(S1,ch);
	 while(ch!='#' || str[i]!='#'){
	 	//自左向右扫描str
		if(IsOperate(str[i]))		//判断str[i]是运算符 
		{			        	//是运算符 :与运算符栈的栈顶元素比较优先级

		   m = getIndex(ch); 
		   n = getIndex(str[i]);		   	 	
		   switch(prior[m][n])
		   {
		   	 case '>'://栈内的更高 
		   	 	if(!Pop(S2,eR))  return ERROR;
		   	 	if(!Pop(S2,eL))  return ERROR;
		   	 	Pop(S1,ch);  
		   	 	result = count(ch,eL,eR);
		   	 	Push(S2,result);
		   	 	getTop(S1,ch);		  
				break;		   	 	
		   	 case '<':
		   	 	Push(S1,str[i]);
		   	 	i++;
		   	 	getTop(S1,ch);
		   	 	break;
		   	 case '='://栈内是(,栈外是)
				Pop(S1,ch) ;//(出栈
				i++;
				getTop(S1,ch); 
				break;
			 default: break;
		   }	
		}else{//是操作数 
			ElemTypeDouble num;
			int j = i;
			double temp = ex1(str,i,j); //取出一个完整数字 
			Push(S2,temp);
			getTop(S2,num);
			i = j;
		}		  
	 }	   	
		 getTop(S1,ch);
	   	if(ch =='#' && str[i]=='#'){
   	 	Push(S2,result);	 
}
	 return OK;
  }
  int main() {
  	string str;
	ElemTypeDouble result = 0;
	cout<<"请输入表达式:"<<endl;
	cin>>str; 				
	EvalutionExpression(str,result);
	cout<<"表达式的值为:"<<endl; 
	cout<<result<<endl;
	return 0;
}
  

 

 

 

 

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值