数据结构总结5——栈2——表达式的求值 by DexterYan

一、基础知识

二、代码实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXSIZE 1024
typedef char elemtype;
typedef struct SequenStack
{
	elemtype data[MAXSIZE];
	int top;
}SequenStack;//顺序栈的结构实现

/*顺序栈的函数*/
SequenStack *Init_SequenStack();//初始化顺序栈 
int SequenStack_Empty(SequenStack *S);//判断顺序栈是否为空 
int SequenStack_Full(SequenStack *S);//判断是否栈满 
int Push_SequenStack(SequenStack *S,elemtype x);//入栈
int Pop_SequenStack(SequenStack *S,elemtype *x);//出栈 
int GetTop_SequenStack(SequenStack *S,elemtype *x);//获取栈顶数据 

/*表达式求值的函数*/
int changeCharToData(char c);
char changeDataToChar(int x);
void calculate(SequenStack *S,char operator);
int arithmeticalOperate(int operand1,int operand2,char operator);
int evaluatePostfixExpression(char *express);//根据后缀表达式express计算表达式的值,并返回计算的结果 
char *transIntoPostfixExpression(char *express);

int main()
{
	char *infixExpression;
	char *postfixExpression;
	int result=0;
	infixExpression=(char *)malloc(10*sizeof(char));
	
	printf("请输入中缀表达式:\n");
	gets(infixExpression);
	postfixExpression=transIntoPostfixExpression(infixExpression);
	printf("转换为后缀表达式:%s\n",postfixExpression);//将中缀表达式转换为后缀表达式 
	
	result=evaluatePostfixExpression(postfixExpression);
	printf("表达式的计算结果:%d\n",result);
	
}

int evaluatePostfixExpression(char *express)//根据后缀表达式express计算表达式的值,并返回计算的结果 
{
	char oprand;
	SequenStack *S;
	char result;
	int i;
	S=Init_SequenStack();
	for(i=0;express[i]!='\0';i++)
	{
		oprand=express[i];
		if(oprand>='0'&&oprand<='9')
		{
			Push_SequenStack(S,oprand);//如果有操作数,就将操作数入栈S 
		}
		else
		{
			calculate(S,oprand);
		}
	}
	Pop_SequenStack(S,&result);//栈S中存放的是表达式的计算结果,通过出栈操作,赋值给result变量,返回调用函数 
	return changeCharToData(result);
}

char *transIntoPostfixExpression(char *express)
{
	char oprand;
	char operator;
	SequenStack *S;
	char *postfixExpress;
	int offset=0;
	int i,len;
	S=Init_SequenStack();
	len=strlen(express);
	postfixExpress=(char *)malloc(len*sizeof(char));//???
	
	for(i=0;express[i]!='\0';i++)
	{
		oprand=express[i];
		switch(oprand)
		{
			case '+':
			case '-':
				while(!SequenStack_Empty(S))
				{
					GetTop_SequenStack(S,&operator);
					if(operator!='(')
					{
						Pop_SequenStack(S,&operator);
						postfixExpress[offset++]=operator;
					}
					else
					{
						break;
					}
				}
				Push_SequenStack(S,oprand);
				break;
			case '*':
			case '/':
				while(!SequenStack_Empty(S))
				{
					GetTop_SequenStack(S,&operator);
					if(operator=='*'||operator=='/')
					{
						Pop_SequenStack(S,&operator);
						postfixExpress[offset++]=operator;
					}
					else
					{
						break;
					}
				}
				Push_SequenStack(S,oprand);
				break;
			case '(':
				Push_SequenStack(S,oprand);
				break;
			case ')':
				while(!SequenStack_Empty(S))
				{
					GetTop_SequenStack(S,&operator);
					if(operator!='(')
					{
						Pop_SequenStack(S,&operator);
						postfixExpress[offset++]=operator;
					}
					else
					{
						Pop_SequenStack(S,&operator);
						break;
					}
				}
				break;
			default:
				postfixExpress[offset++]=oprand;
		}
	}
	while(!SequenStack_Empty(S))
	{
		Pop_SequenStack(S,&operator);
		postfixExpress[offset++]=operator;
	}
	postfixExpress[offset]='\0';
	return postfixExpress;
}

int changeCharToData(char c)
{
	return c-'0';
}

char changeDataToChar(int x)
{
	return x+48;
}

void calculate(SequenStack *S,char operator)
{
	char operand1,operand2;
	int result;
	Pop_SequenStack(S,&operand2);
	Pop_SequenStack(S,&operand1);	
	result=arithmeticalOperate(changeCharToData(operand1),changeCharToData(operand2),operator);
	Push_SequenStack(S,changeDataToChar(result));
}

int arithmeticalOperate(int operand1,int operand2,char operator)
{
	int result;
	switch(operator)
	{
		case'+':
			result=operand1+operand2;
			break;
		case'-':
			result=operand1-operand2;
			break;
		case'*':
			result=operand1*operand2;
			break;
		case'/':
			result=operand1/operand2;
			break;
		return result;
	}
}

//以下为栈的函数实现式 
SequenStack *Init_SequenStack()//初始化顺序栈 
{
	SequenStack *S;
	S=(SequenStack *)malloc(sizeof(SequenStack));
	S->top=-1;
	return S;
}

int SequenStack_Empty(SequenStack *S)//判断顺序栈是否为空 
{
	if(S->top==-1)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

int SequenStack_Full(SequenStack *S)//判断是否栈满 
{
	if(S->top+1==MAXSIZE)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

int Push_SequenStack(SequenStack *S,elemtype x)//入栈
{
	if(S->top>=MAXSIZE-1)
	{
		printf("数据溢出\n");
		return 0;
	}
	S->top++;
	S->data[S->top]=x;
	return 1;
}

int Pop_SequenStack(SequenStack *S,elemtype *x)//出栈 
{
	if(S->top==-1)
	{
		printf("数据栈为空,无法pop\n");
		return 0;
	}
	else
	{
		S->top--;
		*x=S->data[S->top+1];
		return 1;
	}
}

int GetTop_SequenStack(SequenStack *S,elemtype *x)//获取栈顶数据 
{//*x是用来指向读取的数据的,使得主函数中也能访问函数元素 
	if(S->top==-1)
	{
		printf("栈内无数据,读取失败\n");
		return 0;
	}
	else
	{
		*x=S->data[S->top];
		return 1;
	}
}

待修改的要求:
1、把数变成多位,所以要解决是不是一次读一个数,要把一次读的好几个数变成一个多位数,或着浮点数
思路1:入栈时代码实现,把几个位数变成多位数,个位+十位*10+…以此类推,由于浮点数要求,可以把数据类型转换成double类型。
思路2:或者用一个栈存放数字,然后输出字符数组变成一个多位数(函数实现)

猜你喜欢

转载自blog.csdn.net/qq_41259302/article/details/90522953