堆栈实现中缀表达式转后缀表达式及计算表达式的值

本文介绍了如何利用堆栈将中缀表达式转化为后缀表达式,并进行计算。中缀表达式如( 3 + 4 ) × 5 - 6对应的后缀表达式为3 4 + 5 * 6 -。通过读取前缀表达式,按照运算符优先级,将运算符压入堆栈,最终得到没有括号且易于计算的后缀表达式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。算术表达式我们的普通表达式,后缀表达式不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行,例如: 中缀表达式( 3 + 4 ) × 5 - 6,其后缀表达式为34+5*6-

输入格式说明:

输入在一行内给出不超过30个字符的前缀表达式,包含+、-、*、\, (, )以及运算数,不同对象(运算数、运算符号)之间以空格分隔。

代码实现如下:

#include <stdio.h>
#include <malloc.h>
#include <string.h>


//符号的结构体,并存储其符号的优先级
typedef struct node{
	char oper;
	int opt;
}Operatoropt;

//存储符号的栈
typedef struct Node{
	Operatoropt operate;
	struct Node *next;
}OperatorStack;

//创建一个新栈
OperatorStack *creat()
{
	OperatorStack *head;
	head = (OperatorStack *)malloc(sizeof(OperatorStack));
	head->next = NULL;
	return head;
}

//返回为1,则为空,返回不为1,则不为空
int IsEmpty(OperatorStack *head)
{
	return (head->next == NULL);
}

//压入栈
void push(OperatorStack *head, Operatoropt m_operat)
{
	OperatorStack *p;
	p = (OperatorStack *)malloc(sizeof(OperatorStack));
	p->operate = m_operat;
	p->next = head->next;
	head->next = p;
}

//获得栈顶元素的值
Operatoropt TopElement(OperatorStack *head)
{
	Operatoropt operate;
	operate = head->next->operate;
	return operate;
}

//弹出栈
void pop(OperatorStack *head)
{
	OperatorStack *p;
	p = (OperatorStack *)malloc(sizeof(OperatorStack));
	if(IsEmpty(head))
		printf("null");
	else
	{
		p = head->next;
		head->next = p->next;
		free(p);
	}
}

//栈的输出

void output(OperatorStack *head)
{
	OperatorStack *p;
	p = head->next;
	while(p != NULL)
	{
		printf("%c",p->operate);
		p = p->next;
	}
}

int main()
{

	char exp[20] = "";
	char *str = &exp;


	Operatoropt m_operate, top_stack_element;
	OperatorStack *expression;				//表达式的操作符的栈
	gets(str);

	expression = (OperatorStack *)malloc(sizeof(OperatorStack));
	expression = creat();	
	
	while(*(str) != '\0')
	{
		
		if ((*str == '+') || (*str == '-') || (*str == '*') || (*str == '/') || (*str == '(') )
		{
			switch(*str)
			{
			case '+':m_operate.oper = '+';m_operate.opt = 1;break;
			case '-':m_operate.oper = '-';m_operate.opt = 1;break;
			case '*':m_operate.oper = '*';m_operate.opt = 2;break;
			case '/':m_operate.oper = '/';m_operate.opt = 2;break;
			case '(':m_operate.oper = '(';m_operate.opt = 3;break;
			default:break;
			}
			if (IsEmpty(expression))     //如果栈为空,则把此元素压入栈中
				push(expression, m_operate);
			else if (top_stack_element.oper == '(')//如果栈顶元素为(,则把运算符直接压入栈中
				push(expression, m_operate);
			else
			{
				if (top_stack_element.opt >= m_operate.opt) //如果栈顶元素不是(,且优先级高于或者等于新的操作符,则出栈,并且把新的操作符压入栈中
				{
					printf("%c", top_stack_element.oper);
					pop(expression);
					push(expression, m_operate);					
				}
				else
					push(expression, m_operate);//新的操作符比栈顶元素的优先级高,压入栈中
			}
			top_stack_element = TopElement(expression);//获取栈顶元素
		}
		else if(*str == ')')
		{
			while(top_stack_element.oper != '(')  //当遇到)里,把栈顶元素弹出,并且打印,直到弹出的元素为(就停止(此处需要一个错误判断)
			{
				printf("%c", top_stack_element.oper);
				pop(expression);
				top_stack_element = TopElement(expression);
			}
			pop(expression);
		}else if (*str != ' ')
			{
				printf("%c", *str);
			}
			
		str ++;
	}	
	output(expression);
	
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值