中缀表达式的计算(C/C++实现)

  1. 中缀表达式:我们日常用的数学计算表达式

  2. 后缀表达式(逆波兰表达式):复杂的或者带括号的四则运算,需要先将中缀表达式转化为后缀表达式方便计算机识别,计算时从左往右扫描,数字就入数据栈,直到扫出操作符,先后弹出两个数据栈数据调换顺序进行相应操作,再把每次计算结果压栈,以此类推,最后剩下的就是计算结果

  3. 前缀表达式:与后缀表达式相反,计算时从右往左依次扫描

  4.  
    举例
    中缀5+8*2/4+3+4*2*3/3-6运算符放在中间
    后缀582*4/+3+42*3*3/+6-运算符放在后面
    前缀+5+/*824+3-/**42336运算符放在前面

 

 

 

 

#include<stdio.h>
#include<string.h>
#define MaxSize 20

//中缀表达式转后缀,对后缀表达式从左往右扫描计算

//代码有待完善 
//只支持个位数的整数间运算,不处理括号,且定义为顺序栈扩容不方便 
 
//1、定义数据栈 
typedef struct{
	int data[MaxSize];
	int top;
}DataStack;

void InitData(DataStack &data){
	data.top=-1;
	return;
}

bool PushData(DataStack &data,int e){
	if(data.top+1<MaxSize){
		data.data[++data.top]=e;
		return true;
	} 
	return false;	
}

bool PopData(DataStack &data,int &e){
	if(data.top<0){
		return false;
	}
	e=data.data[data.top--];
	return true;
}

bool IsEmptyData(DataStack &data){
	return data.top==-1;
}

//2、定义操作栈
typedef struct{
	char opChar[MaxSize];
	int top;
}OpStack; 

void InitOp(OpStack &op){
	op.top=-1;
	return;
}

bool PushOp(OpStack &op,char opChar){
	if(op.top<MaxSize||op.top>-2){
		op.opChar[++op.top]=opChar;
		return true;
	}
	return false;
}

bool PopOp(OpStack &op){
	if(op.top<0||op.top>MaxSize-1){
		return false;
	}
	op.top--;
	return true;
}

bool IsEmptyOp(OpStack &op){
	return op.top==-1;
}
 
//3、将中缀表达式转为后缀
char result[MaxSize];//避免返回临时变量地址 
char* MiddleToBehind(char str[],int len){
	
	int top=-1;
	
	OpStack op;
	InitOp(op);
	 
	for(int i=0;i<len;i++){
		if(str[i]>='0'&&str[i]<='9'){
			result[++top]=str[i];
		}else{
			if(IsEmptyOp(op)){
				PushOp(op,str[i]);
				continue;
			}else{
				switch(str[i]){
					case '+':
					case '-':
						while(!IsEmptyOp(op)){
						   	result[++top]=op.opChar[op.top];
						   	PopOp(op);
						}
						break;
					case '*':
					case '/':
					 	if(op.opChar[op.top]=='+'||op.opChar[op.top]=='-'){
					 		break;
						}else{
							while(!IsEmptyOp(op)){
								if(op.opChar[op.top]=='+'||op.opChar[op.top]=='-'){
									break;
								}
						   		result[++top]=op.opChar[op.top];
						   		PopOp(op);	
							}
						}
				    	break;	
				}
				PushOp(op,str[i]);
			}
		}
	} 
	//如果运算符栈不为空则依次取出 
	if(!IsEmptyOp(op)){
			while(!IsEmptyOp(op)){
				result[++top]=op.opChar[op.top];
				PopOp(op);
			}
	}
	
	return result; 
} 

//4、计算后缀表达式的值
int BehindResult(char *str,int len){
	DataStack data;
	InitData(data);
	for(int i=0;i<len;i++){
		if(str[i]>='0'&&str[i]<='9'){
			PushData(data,str[i]-'0');
		}else{
			int num,first,second;
			//取出运算的两个数 
			PopData(data,second);
			PopData(data,first);
			switch(str[i]){
				case '+':
					num=first+second;
					break;
				case '-':
					num=first-second;
					break;
				case '*':
					num=first*second;
					break;
				case '/':
					num=first/second;
					break;
			}
			//将结果入栈 
			PushData(data,num);
		}
	}
	int res;
	PopData(data,res);
	return res;
} 
int main(){
	int resultLen=0;
	char str[20]="5+8*2/4+3+4*2*3/3-6";
	printf("中缀表达式为:%s\n",str);
	char *result=MiddleToBehind(str,19);
	printf("后缀表达式为:%s\n",result);
	printf("计算结果为:%d\n",BehindResult(result,19)); 
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值