数据结构之栈的应用:中缀表达式求值

Posted Zhi Zhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之栈的应用:中缀表达式求值相关的知识,希望对你有一定的参考价值。

一、问题

输入一个中缀表达式,先输出该表达式的后缀表达式,再输出运算结果。

输入:6*(5+(2+3)*8+3)

输出结果1:6 5 2 3 + 8 * + 3 + *

输出结果2 :288

二、中缀表达式转为后缀表达式

算法思路:从头到尾读取中缀表达式的每个对象,对不同对象按不同的情况处理。

① 运算数: 直接输出;

② 左括号: 压入堆栈;

③ 右括号: 将栈顶的运算符弹出并输出, 直到遇到左括号(出栈,不输出);

④ 运算符:

              • 若当前运算符的优先级大于栈顶运算符时,则把它压栈;

              • 若当前运算符的优先级小于等于栈顶运算符时,将栈顶运算符弹出并输出;再比较新的栈顶运算符,直到该运算符大于栈顶运算符优先级为止,然后将该运算符压栈;

⑤ 若各对象处理完毕,则把堆栈中存留的运算符一并输出。

三、程序实现

1)从键盘依读取一串字符,包括运算数(整数)和运算符,存入到字符数组a;

2)将字符数组a 输入到中缀表达式转换为后缀表达式的函数,输出带空格的后缀表达式;

3)在中缀表达式转换为后缀表达式的函数中设置了一个存放后缀表达式的临时字符数组temp,且数组temp以\\0结尾;

4)改写博文数据结构之栈的应用(二):逆波兰计算器的程序求后缀表达式的值,得到中缀表达式的最终运算结果。

完整代码如下:

#include<stdlib.h>
#include<stdio.h>
#include<ctype.h>
#define size 100
#define maxbuffer 20

// 一般顺序栈的描述
typedef char SElementType;
typedef struct
{
	SElementType *array;     // 存放元素的数组
	int top;                // 栈的栈顶下标
	int capacity;           // 容量
}SeqStack;

// 1.一般顺序栈的创建
SeqStack* createStack(int capacity)
{
	SeqStack *S;
	S = (SeqStack*)malloc(sizeof(SeqStack));
	S->top = -1;
	S->capacity = capacity;
	S->array = (SElementType*)malloc(capacity*sizeof(SElementType));

	return S;
}

// 2.判断栈是否满
int full(SeqStack *S)
{
	if (S->top >= S->capacity - 1)
		return 1;
	else
		return 0;
}

// 3.进栈
void push(SeqStack *S, SElementType x)
{
	if (full(S))
		return;   // 栈满
	else
	{
		S->top++;
		S->array[S->top] = x;
		return;
	}
}

// 4.判断栈是否空
int empty(SeqStack *S)
{
	if (S->top == -1)
		return 1;
	else
		return 0;
}

// 5.出栈
void pop(SeqStack *S)
{
	if (empty(S))
		return;  // 栈空
	else
	{
		S->top--;
		return;
	}
}

// 6.取栈顶元素
SElementType top(SeqStack *S)
{
	return S->array[S->top];
}

// 比较运算符的优先级
bool compare(char y,char x)   // y为当前运算符,x为栈顶运算符,当前运算符大于栈顶运算符为真,否则为假
{
	if (y == '+' || y == '-')
		if (x == '(')
			return true;
		else
			return false;
	else if (y == '*' || y == '/')
		if (x == '+' || x == '-' || x == '(')
			return true;
		else
			return false;
	else
		return false;
}

// 中缀表达式转换为后缀表达式
void expression(char str[])
{
	SeqStack *s;
	int j = 0;
	char temp[maxbuffer];   // 存放后缀表达式
	s = createStack(size);  // 创建一个栈

	for (int i = 0;str[i] != '\\0';i++)
	{
		if (isdigit(str[i]))   // 运算数
		{
			printf("%c ", str[i]);
			temp[j] = str[i];
			j++;
		}
		else if (str[i] == '(')   // 左括号
		{
			push(s, str[i]);
		}
		else if (str[i] == ')')   // 右括号
		{
			while (1)
			{
				SElementType x = top(s);
				pop(s);

				if (x == '(')
					break;
				else
					printf("%c ", x);
					temp[j] = x;
					j++;
				
			}
		}
		else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')   // 运算符
		{
			while (1)
			{
				SElementType x = top(s);
				if(empty(s))  // 栈空
				{
					push(s, str[i]);
					break;
				}

				if (compare(str[i],x))   // 当前运算符大于栈顶运算符
				{
					push(s, str[i]);
					break;
				}
				pop(s);
				printf("%c ", x);
				temp[j] = x;
			}
		}
	}
	SElementType x = top(s);
	printf("%c ", x);
	temp[j] = x;
	j++;
	temp[j] = '\\0';

}

int main()
{
	char a[] = "6*(5+(2+3)*8+3)";

	printf("输出的后缀表达式为:\\n");
	expression(a);

	return 0;
}

如果你觉得这篇博文不错,动动手指点个赞再走吧,对于博文内容有疑问的朋友,欢迎你在下方评论区留言哦。

支持我的朋友请一键三连:点赞+收藏+关注。

不定期更新!

以上是关于数据结构之栈的应用:中缀表达式求值的主要内容,如果未能解决你的问题,请参考以下文章

C语言 任意表达式求值。(栈的应用

中缀表达式求值问题(栈的应用)

栈的典型应用-表达式求值

栈的应用—算术表达式求值

中缀表达式转换成后缀表达式并求值

数据结构 栈的应用 --表达式求值