逆波兰表达式

6 篇文章 0 订阅

//逆波兰表达式思路:构建两个栈,一个为数值栈,一个为运算符栈。
//遇到栈内的运算符比字符串中的运算符低,就压栈,否则,出栈,并且数值栈元素出栈,并做计算
//然后将计算结果压栈
//重复此过程,最后将字符栈中字符出空,数值栈中元素压栈,输出栈底元素。

#include<bits/stdc++.h>
#define N 81
using namespace std;
int Level(char op)
{
	int k;
	switch(op){//返回优先级 
		case '*':
		case '/':k=2;
		break;
		case '+':
		case '-':k=1;
		break;
		case '(':k=0;
		break;
		case '@':k=-1;
	}
	return k;
}
int Cal(int x1,int x2,char op)//计算函数 
{
	switch(op){
		case '*':return x1*x2;//接收的字符op为‘*’ 
		case '/':return x2/x1;
		case '+':return x1+x2;
		case '-':return x2-x1;
	}
} 
void Process(int *vals,char *ops,int *Pvaltop,int *Poptop)//出栈-出栈-计算-入栈函数 
{
	int x1,x2;
	char op;
	x1=vals[(*Pvaltop)--];//出栈 
	x2=vals[(*Pvaltop)--];//出栈 
	op=ops[(*Poptop)--];//出栈 
	vals[++(*Pvaltop)]=Cal(x1,x2,op);//计算并压栈 
} 
int Compute(char s[])
{
	int *vals;
	char *ops;
	int val,Valtop=-1,Optop=0,i;//val用于存储最后的计算结果,Valtop为数字栈栈顶指针,Optop为字符栈栈顶指针,其栈底存放‘@’用作标记 
	//建栈
	vals=(int *)malloc(N*sizeof(int));
	ops=(char *)malloc(N*sizeof(char));
	ops[Optop]='@';//存储在栈底的标记字符 
	//遍历中缀表达式
	i=0;
	int y;
	while(s[i]){
		if(s[i]>='0'&&s[i]<='9'){//每一次第一个字符是数字字符 
			y=0;
			while(s[i]>='0'&&s[i]<='9'){//从第一个数字字符到出现运算符的这段,计算并压入栈中 
				y=y*10+s[i]-'0';
				i++;//i控制向后遍历 
			}
			vals[++Valtop]=y;//将计算出的结果压栈 
			i--;//为了和后面统一,i退回到运算符前面的一个数字字符处 
		}
		else if(s[i]=='('){//遇到左括号就压栈 
			ops[++Optop]=s[i];
		}
		else if(s[i]==')'){//遇到右括号就出栈到第一个左括号处 
			while(ops[Optop]!='('){
				Process(vals,ops,&Valtop,&Optop);//出栈-出栈-计算-入栈 函数 (将出栈元素计算) 
			}
			Optop--;//将左括号也出栈 
		}
		else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'){//运算符就要比较优先级,a[i]和栈顶元素比较高者直接入栈,否则出栈 
			while(Level(s[i])<=Level(ops[Optop])){//s[i]优先级比栈顶元素优先级低,出栈计算 
				Process(vals,ops,&Valtop,&Optop);
			}
			ops[++Optop]=s[i];//s[i]优先级比栈顶元素优先级高,直接压栈 
		}
		i++;//i+1,继续遍历数组 
	}
	while(Optop){//将字符栈清空,并结合数字栈进行计算 
		Process(vals,ops,&Valtop,&Optop);
	}
	val=vals[Valtop];//数字栈栈底存放的即为所求 
	free(vals);//释放malloc分配的动态单元 
	free(ops);
	return val;
}
int main()
{
	char s[N];
	int val;
	cout<<"请输入一个中缀表达式:";
	gets(s);
	val=Compute(s);
	cout<<"请输出中缀表达式及计算结果:";
	cout<<s<<"="<<val;
	return 0; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值