SCAU华南农业大学8588表达式求值

这道题是结合书本和SCAU 8588 表达式求值_小汤汤汤汤的博客-CSDN博客这篇博文写出来的。

加了挺多的注释,看起来还行。

#include<iostream>
using namespace std;
#include<malloc.h> 
#include<stdio.h> 
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量

typedef int SElemType; // 定义栈元素类型
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等

struct SqStack
{
     SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
     SElemType *top; // 栈顶指针
     int stacksize; // 当前已分配的存储空间,以元素为单位
}; // 顺序栈

Status InitStack(SqStack &S)       
{   
// 构造一个空栈S,该栈预定义大小为STACK_INIT_SIZE
	S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
     if(!S.base) return ERROR;
	 S.top=S.base;
	 S.stacksize=STACK_INIT_SIZE;
	 return OK;
}

Status Push(SqStack &S,SElemType e)   
{   
// 在栈S中插入元素e为新的栈顶元素
	if(S.top-S.base>=S.stacksize)
	{
		S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!S.base) return ERROR;
		S.top=S.base+S.stacksize;
		S.stacksize+=STACKINCREMENT;
	}
	*S.top++=e;
	return OK;
}

Status Pop(SqStack &S,SElemType &e)   
{   
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
	if(S.top==S.base) return ERROR;
     e=*--S.top;
	 return OK;
}

Status GetTop(SqStack S,SElemType &e)   
{    
// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
	if(S.top==S.base) return ERROR;
    e=*(S.top-1);
	return OK;
}

int Precede(char ch1,char ch2)//判断优先级 ,按照书本3.1写算符之间的优先级 
{
	char r;
	switch (ch2)//以第二个来分情况,也就是3.1的表竖着来看 
	{
		case '+':
		case '-':
			{
				if(ch1=='('||ch1=='=')
					r='<';
				else r='>';
			}
			break;//加减可以归到一类,返回的是大于号还是小于号,看表就好。 
		case '*':
		case '/':
			{
				if(ch1=='+'||ch1=='-'||ch1=='('||ch1=='=')
					r='<';
				else r='>';
			}
			break;//乘除可以归到一类,返回的是大于号还是小于号,看表就好。 
		case '(':
			{
				if(ch1==')')
					exit(ERROR);//左括号遇到左括号就报错,其余都输出<的优先级 
				else r='<';
			}
			break;
		case ')':
			{
				if(ch1=='(')
					r='=';//右括号遇到左括号就返回=,后面对=的操作就是把左括号也弹开,这样一对符号就处理完了 
				else if(ch1=='=')
					exit(ERROR);
				else r='>';
			}
			break;
		case '=':
			{
				if(ch1=='=') r='=';//读到=证明到了末尾,对=的操作时弹出,弹完最后一个=号后就结束 
				else if(ch1=='(') exit(ERROR);//读到=还有左括号就证明有问题,报错。 
				else r='>';
			}
			break;
	}
	return r;//就是记得每个case要带上break。 
}

int Operate(int a,int x,int b)
//简单的一个四则运算器,注意,在栈里,我是先Pop得到b再得到a的,也就是a是前运算因子,b是后
//另外,注意中间操作符op传过来也要用int来接收。 
{
	int ans ;
	switch (x)
	{
		case '+':
			ans = a+b;
			break;
		case '-':
			ans = a-b;
			break;
		case '*':
			ans = a*b;
			break;
		case '/':
			ans = a/b;
			break;
	}
	return ans;
}

int main()
{
	SqStack tr,nd;//tr是操作栈,nd是运算因子栈 
	char ch;
	int e,num=0;
	InitStack(tr);InitStack(nd);//初始化并定义必要的变量。 
	Push(tr,'=');//标志一个=压到栈底作为结束标志 
	cin>>ch;//开始读取输入的第一个字符 
	GetTop(tr,e);//弹出一个e,是为了写循环的条件 
	
	while(ch!='='||e!='=')//如果栈底的=标志,和新输入的最后一个也是=,证明循环结束 
	{
		if(ch>='0'&&ch<='9')//因为一个一个输入的时候是字符,所以要把它变成int 
		{
			num=0;
			while(ch>='0'&&ch<='9')//经典的扫字符变整形循环
			{
				num=num*10+(ch-'0'); 
				cin>>ch;
			}
			Push(nd,num);//把结果压到运算因子栈中 
		}
		else//如果是操作符,进行优先级比较 
		{
			switch(Precede(e,ch))
			{
				case '<'://优先级低,压栈,扫下一个字符,break 
					Push(tr,ch);
					cin >> ch;
					break;
				case '='://优先级相等,用一个无用的变量接收弹出,break 
						int t;
						Pop(tr,t);
						cin>>ch;
					break;
				case '>'://优先级高,做运算,把结果压回栈中,break 
					{
						int a,b,ret = 0,op;//注意这里的操作符都是用int来存贮的,所以op也是int 
						Pop(nd,b);
						Pop(nd,a);
						Pop(tr,op);
						ret=Operate(a,op,b);
						Push(nd,ret);
					}
					break;
			}
		}
		GetTop(tr,e);//取操作栈的栈顶元素,以作循环的判断,和优先级比较。
		//注意看上面while循环中,无论是字符栈还是运算因子栈,都是处理完后实时扫下一个字符,更新ch的 
	}
	int answer;
	Pop(nd,answer);//运算因子栈中的最后一个数就是答案,如果没有溢出int的话 
	cout << answer;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值