表达式求值(数据结构c语言版48页)

        写文章记录自己的菜鸟学习过程,报名了蓝桥杯,现在正在备战蓝桥杯。近期一直在做栈的相关题目。今天这道题我整整做了一天,可能是因为自己菜的原因把。今天卡到了算符优先级的问题上了,我的第一反应是采用if分支结构书写优先级,但是漏洞百出,一直到下午6点多的时候,自己去网上搜索了一下,参考了@跨考上浙大这位老哥的文章,自己才恍然大悟。在这道题母上学到‘映射’这个,这位老哥是吧算符的优先级看成一张二维表,用一张二维数组出错起来,让后在写一个函数有两个switch多分支结构得到i,j最后得出优先级。

          我的使用getchar函数一个一个字符处理的,应该可用一个string 类型或者数组类型的来 处理,归根结底都是一个个来处理的,做了几个栈相关的题目了,几乎都是一个一个字符处理的。并且感觉c++STL挺好用。这道题经典但是不是很难。今天就完事了。     


#include<cstdio>
#include<iostream> 
#include<stack>
#include<string.h>
//int i=0;
using namespace std;

int Operate(int a,char fu,int b)//运算函数啊,a,b代表数字,fu代表运算符;
{
	int c=0;//作为返回变量
	//printf("%d %d",a,b);
	switch(fu)
	{
		case '+':c=a+b;break;
		case '-':c=a-b;break;
		case '*':c=a*b;break;
		case '/':c=a/b;break;
		default :return 0;	
	}	
	return c;
} 

char Priority[7][7]={ 
    {'>','>','<','<','<','>','>'},  
    {'>','>','<','<','<','>','>'},  
    {'>','>','>','>','<','>','>'},  
    {'>','>','>','>','<','>','>'},  
    {'<','<','<','<','<','=','0'},   // 此行"("=")"表示左右括号相遇,括号内运算已完成 
    {'>','>','>','>','0','>','>'},  
    {'<','<','<','<','<','0','='}    // "=" 表示整个表达式求值完毕 
	};                               //  "0"表示不可能出现这种情况 ( 语法错误 ) 
	
//Precede 用于判断运算符栈栈顶运算符 a1 与读入运算符 a2 之间的优先关系函数 
char Procede(char a,char b){   // 建立 pre[][] 到 运算符间的映射关系 
    int i,j;  
    switch(a){  
        case'+':i=0;break;  
        case'-':i=1;break;  
        case'*':i=2;break;  
        case'/':i=3;break;  
        case'(':i=4;break;  
        case')':i=5;break;  
        case'#':i=6;break;   // # 是表达式的结束符 
    }  
    switch(b){  
        case'+':j=0;break;  
        case'-':j=1;break;  
        case'*':j=2;break;  
        case'/':j=3;break;  
        case'(':j=4;break;  
        case')':j=5;break;  
        case'#':j=6;break;  
    }  
    return Priority[i][j];  
}

int EvaluateExpression(){
	stack<int> opnd;
	stack<char> optr;//运算栈 
	char theta;
	int a=0,b=0;
	optr.push('#');
	char c=getchar();
	//printf("%c",c); 
	char temp;
	//temp=optr.top();
	while(c!='#'||optr.top()!='#'){
		if(c>=48 && c<=57){c=c-'0';opnd.push(c);c=getchar();}
		else {
			switch(Procede(optr.top(),c)){
				case '<':{   //栈顶元素优先级低
					optr.push(c); c=getchar();
					break;
				}   
				case '=':{
					//printf("%d",++i);	   //去括号并接受下一个字符
					optr.pop(); c=getchar(); 
					break;
				}
				case '>':{   //退栈并将运算符结果入站 
					theta=optr.top();optr.pop();	
					b=opnd.top();opnd.pop();
					a=opnd.top();opnd.pop();
					opnd.push(Operate(a,theta,b));
					//printf("%d",++i);                                    
					//printf("%c",optr.top());
					//printf("%c",c);//a,b的进栈的顺序,所以先取b,后取a; 
					break;
				}
			}	
		}
	}
	return opnd.top();
 } 
int main()
{
	int ans;
	ans=EvaluateExpression();
	printf("%d",ans);
	//printf("%c",Precede('#','>'));
	return 0;
} 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值