栈实现中缀表达式求解

算术表达式有三种:中缀表达式、前缀表达式、后缀表达式,日常用的算术表达式为中缀表达式,其计算数值虽然一目了然,却不容易被计算机解释,其主要原因是在中缀表达式中,各运算符的优先级不同,不能简单地从表达式的左边直接计算到右边。所以要用两个栈实现,一个用来放操作数,一个用来放运算符。

算法步骤:
1.初始化并简历两个栈,一个用来放操作数OPND,一个用来放运算符OPTR,首先将操作数栈置为空栈,表达式起始符’#’为运算符栈底元素。
2.输入一个后缀表达式(以#结束),依次读入表达式中每个字符,若是操作数进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先级后做相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为’#’)。
3.算法中还调用了两个函数。其中Precede是判定运算符栈顶运算符θ1与读入运算符θ2之间优先关系的函数;Operateo为进行具体运算的函数,计算aθb并返回运算结果。

功能实现
1.元素类型,结点类型
typedef struct Stack
{
	int* top;
	int* base;
	int capacity;
}SqStack1;//操作数栈
typedef struct Stack
{
	char* top;
	char* base;
	int capacity;
}SqStack2;//运算符栈
2.栈的基本操作
Status Initstack(SqStack* S)//栈初始化
{
	S->base = (int*)malloc(MAXSIZE * sizeof(int));
	if (!S->base) exit(OVERFLOW);
	S->top = S->base;
	S->capacity = MAXSIZE;
	return OK;
}
Status Push(SqStack* S, ElemType e)//入栈
{
	if (S->top - S->base >= S->capacity)
	{
		S->base = (int*)realloc(S->base, (YICHUHOU + S->capacity) * (sizeof(int)));
		if (!S->base) exit(OVERFLOW);
		S->top = S->base + S->capacity;
		S->capacity += YICHUHOU;
	}
	*S->top = e;
	S->top++;
	return OK;
}
Status Pop(SqStack* S, ElemType& e)//出栈
{
	if (S->top == S->base)return ERROR;
	--S->top;
	e = *S->top;
	return OK;
}
Status Gettop(SqStack* S, ElemType& e)//取栈顶元素
{
	if (S->top == S->base)return ERROR;
	e = *(S->top - 1);
	return e;
}
核心代码讲解
4.	运算函数
int Operator(int a, char ch,int b)//对操作数进行相应计算
{
	int c;
	switch (ch)
	{
	case '*':
		c = a * b;
		break;
	case '-':
		c = b-a;
		break;
	case '+':
	c = b + a;
		break;
	case '/':
		c = b / a;
		break;
	default:
		break;
	}
	return c;
}

运算符优先级
在这里插入图片描述

char Precede(char a,char b)//判段运算符优先级
{
int i,j;
//用二维数组存储运算符的优先级
char Table[8][8]={
' ','+','-','*','/','(',')','#',
'+','>','>','<','<','<','>','>',
'-','>','>','<','<','<','>','>',
'*','>','>','>','>','<','>','>',
'/','>','>','>','>','<','>','>',
'(','<','<','<','<','<','=',' ',
')','>','>','>','>','>',' ','>',
'#','<','<','<','<','<',' ','=',
};//优先级表格(根据上图)


for(i=0;i<8;i++)//纵坐标寻找
if(Table[0][i]==a)
break;
for(j=0;j<8;j++)//横坐标寻找
if(Table[j][0]==b)
break;
return Table[j][i];//返回查找到的字符,即优先级>,<或=
}
计算函数
int result(SqStack1 *OPND,SqStack2 *OPTR)
{
	char a=0;
	char theta;
	int b,c,number=0;
	IntInitstack(OPND);
	CharInitstack(OPTR);
	CharPush(OPTR,'#');// 表达式起始符’#’为运算符栈底元素
	a=getchar();//输入一个字符
	while(a!='#'||CharGettop(OPTR)!='#')
	{

		if(a>=0&&a<=9)//判断是否为数字
		{
			number=0;
			while(!Is(a))
			{
				number=number*10+(a-48);//处理多位整数
				a=getchar();
			}
			IntPush(OPND,number);//如果为个位数直接入数字栈
		}
		Else if(Is(a))//Is()是定义的一个判断是否为运算符的函数
			switch(Precede(a,CharGettop(OPTR))//如果是运算符则比较优先级
		{
			case'>'://如果字符a的优先级小于栈顶元素
				CharPush(OPTR,a);
				a=getchar();
				break;
			case'=':
				CharPop(OPTR);
				a=getchar();
				break;
			case'<':
				theta=CharPop(OPTR);
				c=IntPop(OPND);
				b=IntPop(OPND);
				IntPush(OPND,Operate(b,theta,c));
				break;
		}
Else
	printf("表达式不合法");//如果输入表达式有除数字和字符以外其他字符则不合法
		break;
	}
	printf("结果:%d\n",IntGettop(OPND));
	return OK;
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAXSIZE 100
#define YICHUHOU  10
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef  int Status;
typedef int ElemType;
typedef struct intStack
{
	int* top;
	int* base;
	int capacity;
}SqStack1;
typedef struct charStack
{
	char* top;
	char* base;
	int capacity;
}SqStack2;
Status IntInitstack(SqStack1* S1)
{
	S1->base = (int*)malloc(MAXSIZE * sizeof(int));
	if (!S1->base) exit(OVERFLOW);
	S1->top = S1->base;
	S1->capacity = MAXSIZE;
	return OK;
}
Status IntPush(SqStack1* S1, ElemType e)
{
	if (S1->top - S1->base >= S1->capacity)
	{
		S1->base = (int*)realloc(S1->base, (YICHUHOU + S1->capacity) * (sizeof(int)));
		if (!S1->base) exit(OVERFLOW);
		S1->top = S1->base + S1->capacity;
		S1->capacity += YICHUHOU;
	}
	*S1->top = e;
	S1->top++;
	return e;
}
Status IntPop(SqStack1* S1)
{
	 ElemType e;
	if (S1->top == S1->base)return ERROR;
	--S1->top;
	e = *S1->top;
	return e;
}
Status IntGettop(SqStack1* S1)
{
	 ElemType e;
	if (S1->top == S1->base)return ERROR;
	e = *(S1->top - 1);
	return e;
}
Status CharInitstack(SqStack2* S2)
{
	S2->base = (char*)malloc(MAXSIZE * sizeof(char));
	if (!S2->base) exit(OVERFLOW);
	S2->top = S2->base;
	S2->capacity = MAXSIZE;
	return OK;
}
Status CharPush(SqStack2* S2,char e)
{
	if (S2->top - S2->base >= S2->capacity)
	{
		S2->base = (char*)realloc(S2->base, (YICHUHOU + S2->capacity) * (sizeof(char)));
		if (!S2->base) exit(OVERFLOW);
		S2->top = S2->base + S2->capacity;
		S2->capacity += YICHUHOU;
	}
	*S2->top = e;
	S2->top++;
	return OK;
}
char CharPop(SqStack2* S2)
{
	char e;
	if (S2->top == S2->base)return ERROR;
	--S2->top;
	e = *S2->top;
	return e;
}
char CharGettop(SqStack2* S2)
{
	char e;
	if (S2->top == S2->base)return ERROR;
	e = *(S2->top - 1);
	return e;
}
int Operate(int a, char ch,int b)//对操作数进行相应计算
{
	int c;
	switch (ch)
	{
	case '*':
		c = a * b;
		break;
	case '-':
		c = a-b;
		break;
	case '+':
		c = b + a;
		break;
	case '/':
		c = a / b;
		break;
	default:
		break;
	}
	return c;
}
char Precede(char a,char b)//判段运算符优先级
{
int i,j;
char Table[8][8]={
' ','+','-','*','/','(',')','#',
'+','>','>','<','<','<','>','>',
'-','>','>','<','<','<','>','>',
'*','>','>','>','>','<','>','>',
'/','>','>','>','>','<','>','>',
'(','<','<','<','<','<','=',' ',
')','>','>','>','>','>',' ','>',
'#','<','<','<','<','<',' ','=',
};//优先级表格
for(i=0;i<8;i++)//纵坐标寻找
if(Table[0][i]==b)
break;
for(j=0;j<8;j++)//横坐标寻找
if(Table[j][0]==a)
break;
return Table[j][i];
}
int Is(char c)
{
	if(c=='('||c=='+'||c=='-'||c=='*'||c=='/'||c==')'||c=='#'||c=='^')
		return 1;//如果是操作符返回1
	else 
		return 0;//否则返回0
}
int result(SqStack1 *OPND,SqStack2 *OPTR)
{
	char a=0;
	char theta;
	int b,c,number=0;
	IntInitstack(OPND);
	CharInitstack(OPTR);
	CharPush(OPTR,'#');
	a=getchar();
	while(a!='#'||CharGettop(OPTR)!='#')
	{
		//printf("输入字符:%c",a);
		if(a>='0'&&a<='9')
		{
			number=0;
			while(!Is(a))
			{
				number=number*10+(a-48);//处理多位整数
				a=getchar();
			}
			IntPush(OPND,number);
		}
		else if(Is(a))
			switch(Precede(a,CharGettop(OPTR)))
		{
			case '>':
				CharPush(OPTR,a);
				a=getchar();
				break;
			case '=':
				CharPop(OPTR);
				a=getchar();
				break;
			case '<':
				theta=CharPop(OPTR);
				c=IntPop(OPND);
				b=IntPop(OPND);
				IntPush(OPND,Operate(b,theta,c));
				break;
		}
		else
			printf("表达式不合法");
		break;

	}
	printf("结果:%d\n",IntGettop(OPND));
	return OK;
}
int main()
{
SqStack1 OPND;
SqStack2 OPTR;
IntInitstack(&OPND);
CharInitstack(&OPTR);
printf("输入以#结尾的表达式:\n");
result(&OPND,&OPTR);
return 0;
}

运行结果

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值