C++实验表达式求值

主要功能:

  • 中缀表达式转换为后缀表达式
  • 中缀表达式的计算
  • 后缀表达式的计算

源码:

# include <iostream>
# include <stdlib.h>
using namespace std;
# define MAXSIZE 100
void menu(){
   cout<<" ------------------------------------------------------"<<endl;
		cout<<"表达式求值"<<endl;
		cout<<"1. 中缀表达式到后缀表达式的转换"<<endl;
		cout<<"2. 后缀表达式的计算"<<endl;
		cout<<"3. 中缀表达式的计算"<<endl;
		cout<<"4. 退出"<<endl;
cout<<"-------------------------------------------------------"<<endl;

}
//---------------------------------------------------
typedef struct  //操作数栈的结构体(整形)
{
    int *base;
    int *top;
    int stacksize;
}Stack;
int InitStack(Stack &s)//操作数栈初始化
{
    s.base = new int[MAXSIZE];
    if(!s.base)
        return 0;
    s.top = s.base;
    s.stacksize = MAXSIZE;
    return 1;
}
void Push(Stack &s,int e)//操作数栈入栈
{
    if(s.base-s.top==s.stacksize)
        cout<<"栈满"<<endl;
    else{
        *s.top = e;
        s.top++;
    }
}
void Pop(Stack &s)//操作数栈出栈
{
    if(s.top==s.base)
        cout<<"栈空"<<endl;
    s.top--;
}
int GetTop(Stack &s)//取栈顶元素
{
    if(s.top!=s.base)
        return *(s.top-1);
        else
            return 0;
}
//------------------------------------------------

typedef struct//运算符队列结构体
{
    char *base;
    int front;
    int rear;
}SqQueue;
int InitQueue(SqQueue &s)//初始化队列
{
    s.base = new char[100];
    if(!s.base)
        return 0;
    s.front = s.rear = 0;
    return 1;
}
int QueueLength(SqQueue &s)//求队列长度
{
    return (s.rear+MAXSIZE-s.front)%MAXSIZE;
}
void EnQueue(SqQueue &s,char e)//入队操作
{
    if((s.rear+1)%MAXSIZE==s.front)
        cout<<"队列已满无法入队"<<endl;
    else{
        s.base[s.rear] = e;
        s.rear = (s.rear+1)%MAXSIZE;
    }
}
void DeQueue(SqQueue &s,char e)//出队操作
{
    if(s.rear==s.front)
    {
        cout<<"队列为空无法出队"<<endl;
    }
    else{
        e = s.base[s.front];
        s.front = (s.front+1)%MAXSIZE;
    }
}
char GetHead(SqQueue &s)//取队头元素
{
    if(s.rear!=s.front)
    {
        return s.base[s.front];
    }
}
//----------------------------------------------------------------
typedef struct  //定义运算符栈的结构体
{
    char *base;
    char *top;
    int stacksize;
}SqStack;

int InitStack(SqStack &s)//运算符栈初始化
{
    s.base = new char[MAXSIZE];
    if(!s.base)
        return 0;
    s.top = s.base;
    s.stacksize = MAXSIZE;
    return 1;
}
void Push(SqStack &s,char e)//运算符顺序栈入栈
{
    if(s.base-s.top==s.stacksize)
        cout<<"栈满"<<endl;
    else{
        *s.top = e;
        s.top++;
    }
}
void Pop(SqStack &s,char e)//运算符顺序栈出栈
{
    if(s.top==s.base)
        cout<<"栈空"<<endl;
    s.top--;
    e = *s.top;
}
char GetTop(SqStack &s)//取栈顶元素
{
    if(s.top!=s.base)
        return *(s.top-1);
        else
            return 0;
}
int YouXianJi(char ch){//判断符号的优先级
	int p;
    switch(ch){
	   case '#': p = 0; break;
 	   case '(': p = 1; break;
	   case '+': p = 2; break;
	   case '-': p = 2; break;
	   case '*': p = 3; break;
	   case '/': p = 3; break;
	}
	return p;
}
//--------------------------------------------------------------------------------------
void ZhongZhuanHou(SqStack &S,SqQueue &Q){ //将中缀表达式转换成后缀表达式
    char a[100];//用于存储输入的表达式
	int i,e;
	char ch;
	char *p;
	Push(S,'#');//将#压入方便操作
	cout<<"请输入中缀表达式(以@结束)"<<endl;
	cin>>a;
    for(i=0;a[i]!='@';i++){
		if(a[i]>='0'&&a[i]<='9'){//如果是数字直接入队
		     EnQueue(Q,a[i]);
		}
	     	else{//如果是符号进行以下判断
				if(a[i]=='('){//如果是(直接入栈
				     Push(S,a[i]);
				}
				else if(a[i]==')'){//如果是右括号将栈中压在左括号上的元素依次入队并弹出栈
				do{
                  	EnQueue(Q,GetTop(S));
				    Pop(S,ch);
				}while(GetTop(S)!='(');
				Pop(S,ch);//将左括号弹出
				}
				else{
			while(YouXianJi(a[i])<=YouXianJi(GetTop(S))){//如果读到的运算符优先级比栈顶元素的小,则将栈顶元素入队后弹出栈
			   	EnQueue(Q,GetTop(S));
			     Pop(S,ch);
			}
			if(YouXianJi(a[i])>YouXianJi(GetTop(S))){//如果相反,则直接压入运算符栈
			     Push(S,a[i]);
			}
				}
		}
	}
    while(GetTop(S)!='#'){//读到#说明到栈底了,将栈中的元素依次入队弹出
	    EnQueue(Q,GetTop(S));
		Pop(S,ch);
	}

       Pop(S,ch);//将#也弹出
}
//-----------------------------------------------------------------------------------------------------------------------
int ZhuanHuan(char ch){  //将字符型转换成整形
    switch(ch){
	case '1':return 1;break;
    case '2':return 2;break;
	case '3':return 3;break;
	case '4':return 4;break;
	case '5':return 5;break;
	case '6':return 6;break;
	case '7':return 7;break;
	case '8':return 8;break;
	case '9':return 9;break;
	case '0':return 0;break;
	}
}
int JS(int m,int n,char ch){ //计算表达式
	if(ch=='+'){
	     return m+n;
	}
	if(ch=='-'){
	     return m-n;
	}
	if(ch=='*'){
	     return m*n;
	}
	if(ch=='/'){
	     return m/n;
	}
}
int HouJiSuan(Stack &S,SqQueue &Q){ //后缀表达式计算
	int m,n,p,k,l;
	char ch;
	while(Q.front!=Q.rear){//如果队列不空依次读取队列中的元素
	     ch = GetHead(Q);
		if(ch>='0'&&ch<='9'){//如果队列中的是数字则将字符栈中字符转换成数字在压入操作数栈中
			k = ZhuanHuan(ch);
		    Push(S,k);
		}
		else{//如果读到字符,则在栈中弹出两个数赋值给m和n,计算将结果存入操作数栈中
		    m = GetTop(S);
			Pop(S);
			n = GetTop(S);
			Pop(S);
			p = JS(n,m,ch);
			Push(S,p);
		}
		DeQueue(Q,ch);//出队
	}
	return p;

}
//---------------------------------------------------------------------------------------------------------
typedef struct  //定义操作数栈的结构体
{
    float *base;//可以存入浮点型数据
    float *top;
    int stacksize;
}ShuStack;
int InitShuStack(ShuStack &s)//操作数栈初始化
{
    s.base = new float[MAXSIZE];
    if(!s.base)
        return 0;
    s.top = s.base;
    s.stacksize = MAXSIZE;
    return 1;
}
void Push(ShuStack &s,float e)//操作数入栈
{
    if(s.base-s.top==s.stacksize)
        cout<<"栈满"<<endl;
    else{
        *s.top = e;
        s.top++;
    }
}
void Pop(ShuStack &s)//操作数出栈
{
    if(s.top==s.base)
        cout<<"栈空"<<endl;
    s.top--;
}
float GetTop(ShuStack &s)//操作数栈取栈顶元素
{
    if(s.top!=s.base)
        return *(s.top-1);
        else
            return 0;
}
typedef struct  //定义运算符栈的结构体
{
    char *base;
    char *top;
    int stacksize;
}FuStack;
int InitFuStack(FuStack &s)//运算符栈初始化
{
    s.base = new char[MAXSIZE];
    if(!s.base)
        return 0;
    s.top = s.base;
    s.stacksize = MAXSIZE;
    return 1;
}
void FuPush(FuStack &s,char e)//运算符顺序栈入栈
{
    if(s.base-s.top==s.stacksize)
        cout<<"栈满"<<endl;
    else{
        *s.top = e;
        s.top++;
    }
}
void FuPop(FuStack &s)//运算符顺序栈出栈
{
    if(s.top==s.base)
        cout<<"栈空"<<endl;
    s.top--;
}
int FuGetTop(FuStack &s)//运算符栈取栈顶元素
{
    if(s.top!=s.base)
        return *(s.top-1);
        else
            return 0;
}
//判断是否为数字或小数点
int IsShuDian(char x){
    if((x>='0'&&x<='9')||x=='.')
        return 1;
    return 0;
}
char Precede(char c1,char c2){//    比较两个操作符的优先级
  if(c1=='+')
  {
    if(c2=='+') return  '>';
    else if(c2=='-') return  '>';
    else if(c2=='*') return  '<';
    else if(c2=='/') return  '<';
    else if(c2=='(') return  '<';
    else if(c2==')') return  '>';
    else return  '>';
   }
  else if(c1=='-')
  {
    if(c2=='+') return  '>';
    else if(c2=='-') return  '>';
    else if(c2=='*') return  '<';
    else if(c2=='/') return  '<';
    else if(c2=='(') return  '<';
    else if(c2==')') return  '>';
    else return  '>';
   }
   else if(c1=='*')
  {
    if(c2=='+') return  '>';
    else if(c2=='-') return  '>';
    else if(c2=='*') return  '>';
    else if(c2=='/') return  '>';
    else if(c2=='(') return  '<';
    else if(c2==')') return  '>';
    else return  '>';
   }
   else if(c1=='/')
  {
    if(c2=='+') return  '>';
    else if(c2=='-') return  '>';
    else if(c2=='*') return  '>';
    else if(c2=='/') return  '>';
    else if(c2=='(') return  '<';
    else if(c2==')') return  '>';
    else return  '>';
   }
   else if(c1=='(')
  {
    if(c2=='+') return  '<';
    else if(c2=='-') return  '<';
    else if(c2=='*') return  '<';
    else if(c2=='/') return  '<';
    else if(c2=='(') return  '<';
    else return  '=';

   }
   else if(c1==')')
  {
    if(c2=='+') return  '>';
    else if(c2=='-') return  '>';
    else if(c2=='*') return  '>';
    else if(c2=='/') return  '>';

    else if(c2==')') return  '>';
    else return  '>';
   }
   else
  {
    if(c2=='+') return  '<';
    else if(c2=='-') return  '<';
    else if(c2=='*') return  '<';
    else if(c2=='/') return  '<';
    else if(c2=='(') return  '<';

    else return  '=';
   }
}
float JS1(float m,float n,char ch){ //计算表达式
	if(ch=='+'){
	     return m+n;
	}
	if(ch=='-'){
	     return m-n;
	}
	if(ch=='*'){
	     return m*n;
	}
	if(ch=='/'){
	     return m/n;
	}
}
void ZhongJiSuan(ShuStack &S,FuStack &S1){
      char chuan[MAXSIZE];//用于输入表达式
	  char LinShi[MAXSIZE];
	  int i=0;
	  float f,e1,e2,e3;
	  int j=0;
	  char ch,ch1;
	  cout<<"请输入中缀表达式"<<endl;
	  cin>>chuan;
	  FuPush(S1,'#');//将#压入运算符栈中
	  while(chuan[i]!='#'||FuGetTop(S1)!='#'){//如果表达式没读完或运算符栈还有元素执行循环体
		  if((chuan[i]>='0'&&chuan[i]<='9')||chuan[i]=='.'||((chuan[i]=='-')&&(chuan[i-1]<'0'||chuan[i-1]>'9')&&(chuan[i-1]!=')')))//如果是数字
		  {
			  while((chuan[i]>='0'&&chuan[i]<='9')||chuan[i]=='.'||((chuan[i]=='-')&&(chuan[i-1]<'0'||chuan[i-1]>'9')&&(chuan[i-1]!=')')))
			  {
				LinShi[j]=chuan[i];//将数存到临时数组里
				i++;
				j++;
			  }
			  LinShi[j]='\0';
			  f = atof(LinShi);//调用库函数将临时数组中的数据转换成浮点数
			  Push(S,f);//将数据压入运算数栈
			  j = 0;//将临时存放数据的数组清空用于第二次转换
		  }
		  else{
				  if(Precede(FuGetTop(S1),chuan[i])=='<'){//如果读到的符号比符号栈栈顶元素优先级高则将其压入符号栈
					   FuPush(S1,chuan[i]);
					   i++;
				  }
				 else if(Precede(FuGetTop(S1),chuan[i])=='>'){//如果读到的符号比符号栈栈顶元素优先级低则弹出操作数栈中的两个数计算完后压入运算数栈
					  ch1 = FuGetTop(S1);
					  FuPop(S1);
					  e1 = GetTop(S);
					 Pop(S);
					 e2 = GetTop(S);
					  Pop(S);
					  e3 = JS1(e2,e1,ch1);
					  Push(S,e3);
				  }
				  else/*(Precede(FuGetTop(S1),chuan[i])=='=')*/{//如果优先级相等则弹出运算符
					  FuPop(S1);
					  i++;
				  }

		  }
	  }
	 cout<<"运算结果是"<<GetTop(S)<<endl;
}
main(){
	int n;
	int i;
      SqStack S;
	  SqQueue Q;
	  Stack S1;
	  ShuStack SS;//
	  FuStack S2;//
	  InitShuStack(SS);
      InitFuStack(S2);
	  InitStack(S);
	  InitQueue(Q);
      InitStack(S1);
	  while(1){
	      menu();
		  cout<<"请输入所选功能"<<endl;
		  cin>>n;
		  if(n==1){
		      ZhongZhuanHou(S,Q);
			  for(i=Q.front;i!=Q.rear;i++){
			     cout<<Q.base[i]<<" ";
			  }
			  cout<<endl;
		  }
		  if(n==2){
		      cout<<HouJiSuan(S1,Q)<<endl;
		  }
		  if(n==3){
		      ZhongJiSuan(SS,S2);
		  }
		  if(n==4)
			  break;
	  }
}
/*main(){
   	int i;
	menu();
	 SqStack S;
	 SqQueue Q;
	 Stack S1;
	 char ch;
     InitStack(S);
	 InitQueue(Q);
     InitStack(S1);
	 ZhongZhuanHou(S,Q);
	cout<<HouJiSuan(S1,Q)<<endl;
}*/

//1+2*(3-1+2)-3@
//12.3+-11.3-2#

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二琳爱吃肉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值