(c语言)堆栈计算后缀表达式(包含测试用例)

本实验取材于浙江大学《数据结构》,计算后缀表达式,关键在于理解堆栈的工作顺序

//堆栈的应用案例--表达式求值
//表达式求值的基本步数
//1当读入的是一个运算数时,把它被压入栈中;
//2当读入的是一个运算符时,就从堆栈中弹出适当数量的运算数
//对该运算进行计算,计算结果再压回到栈中。
//处理完整个后缀表达时之后,堆栈顶上的元素就是表达时的结果值

下面利用堆栈的顺序存储进行运算!


#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAXOP 100//操作数序列可能的最大长度
#define INFINITY 1e9//代表正无穷
#define ERROR -1
typedef double ElementType;//将堆栈的元素类型具体化
//类型依次对应运算符、运算符、字符串结尾

typedef enum{num,opr,end} Type;
typedef int Position;
typedef struct SNode *PtrToStack;

struct SNode{
	ElementType *Data;
	Position Top;
	int MaxSize;
};
typedef PtrToStack Stack;
Stack CreateStack(int MaxSize);//生成空堆栈,其最大长度为Maxsize
int IsFull(Stack S);//判断堆栈S是否已满
int Push(Stack S,ElementType X);//将元素item压入堆栈
int IsEmpty(Stack S);//判断堆栈S是否为空
ElementType Pop(Stack S);//删除并返回栈顶元素
Stack CreateStack(int MaxSize){
	Stack S=(Stack)malloc(sizeof(struct SNode));
	S->Data = (ElementType *)malloc(MaxSize*sizeof(ElementType));
	S->Top = -1;
	S->MaxSize = MaxSize;
	return S;
}
int IsFull(Stack S){
	return (S->Top==S->MaxSize-1);
}

int Push(Stack PtrS,ElementType X)
{
	if(IsFull(PtrS)){
		printf("堆栈满");
		return ERROR;
	}else{
		PtrS->Data[++(PtrS->Top)] = X;
		return PtrS->Data[PtrS->Top];
	}
}
int IsEmpty(Stack S){
	return (S->Top==-1);
}
ElementType Pop(Stack PtrS)
{
	if(PtrS->Top==-1){
		printf("堆栈空");
		return ERROR;
	}else{
		return (PtrS->Data[(PtrS->Top)--]);
	}
}
Type Getop(char *Expr,int *start,char *str)
{
	//从*start开始读入下一个对象(操作数或运算符),并
	//保存在字符串str中
	int i=0;
	while((str[0]=Expr[(*start)++])==' ');
	while(str[i]!=' ' && str[i]!='\0')
		str[++i]=Expr[(*start)++];
	if(str[i]!='\0')//如果读到输入结尾
		(*start)--;//start指向结束符
	str[i]='\0';//结束一个对象的获取
	if(i==0) return end;//读到了结束
	else if(isdigit(str[0]) || isdigit(str[1]))
		return num;//表示此时str中存的是一个数字
	else    //表示str不是空串,又不是数字
		return opr; //表示此时str中存的是一个运算符
		
	
}
ElementType PostfixExp(char *Expr)
{
	Stack S;
	Type T;
	ElementType Op1,Op2;
	char str[MAXOP];
	int start=0;
	//申请一个新堆栈
	S=CreateStack(MAXOP);
	Op1 = Op2=0;
	while((T=Getop(Expr,&start,str))!= end){
		//当为读到输入结束时
		if(T==num)
			Push(S,atof(str));
		else{
			if(!IsEmpty(S)) Op2 = Pop(S);
			else Op2 = INFINITY;
			if(!IsEmpty(S)) Op1 = Pop(S);
			else Op2 = INFINITY;
			switch(str[0]){
				case '+':Push(S,Op1+Op2);break;
				case '*':Push(S,Op1*Op2);break;
				case '-':Push(S,Op1-Op2);break;
				case '/':
					if(Op2 != 0.0)
						Push(S,Op1/Op2);
					else{
						printf("falut div is zero\n");
						Op2 = INFINITY;
					}
					break;
				default:
					printf("fault unknown fault%s\n",str);
					Op2 = INFINITY;
					break;
			}
			if(Op2>=INFINITY) break;
		}
	}
	if(Op2<INFINITY)
		if(!IsEmpty(S))
			Op2=Pop(S);
		else
			Op2 = INFINITY;
		free(S);
		return Op2;
}
int main()
{
	char Expr[MAXOP];
	ElementType f;
	gets(Expr);
	f=PostfixExp(Expr);
	if(f<INFINITY)
		printf("%.4f\n",f);
	else
		printf("function is fault\n");
	return 0;
}
发布了63 篇原创文章 · 获赞 2 · 访问量 1449

猜你喜欢

转载自blog.csdn.net/m0_37149062/article/details/105066806