中缀表达式变成后缀表达式

中缀表达式变成后缀表达式
3+42/(5-4+1)
1、加括号 ( 3+((4
2)/ ((5-4)+1) ))
2、把符号放在括号外面 ( 3 ((4 2)* ((5 4)- 1) +)/)+
3、除去括号 3 4 2 * 5 4 - 1 +/+
在这里插入图片描述
转换过程需要用到栈,具体过程如下:

1)如果遇到操作数,我们就直接将其输出。

2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。

3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。

4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素 (或者栈为空) 为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到 " ) " 的情况下我们才弹出 " ( ",其他情况我们都不会弹出 " ( "。

5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。

#pragma once

/*********************************************************************************************************
  运算符优先级,数值越小优先级越高
*********************************************************************************************************/
#define OPERA_PRIO_PLUS_IN            4                                 /*  栈内 +                      */
#define OPERA_PRIO_MINUS_IN           4                                 /*  栈内 -                      */
#define OPERA_PRIO_MULTIPLY_IN        2                                 /*  栈内 *                      */
#define OPERA_PRIO_DIVISION_IN        2                                 /*  栈内 /                      */
#define OPERA_PRIO_LEFT_BRACKETS_IN   10                                /*  栈内 (                      */

#define OPERA_PRIO_PLUS_OUT           5                                 /*  栈外 +                      */
#define OPERA_PRIO_MINUS_OUT          5                                 /*  栈外 -                      */
#define OPERA_PRIO_MULTIPLY_OUT       3                                 /*  栈外 *                      */
#define OPERA_PRIO_DIVISION_OUT       3                                 /*  栈外 /                      */
#define OPERA_PRIO_LEFT_BRACKETS_OUT  1                                 /*  栈外 (                      */
#define OPERA_PRIO_RIGHT_BRACKETS_OUT 10                                /*  栈外 )                      */
#define OPERA_PRIO_ERR                -1 
#include <stdio.h>
#include <ctype.h>
#include "lstack.h"
#include "prio.h"

// 获取运算符的优先级
int Priority(char opera,bool InStack)
{
	int prio=OPERA_PRIO_ERR;
	if(InStack)
	{
		switch(opera)
		{
		case '+':
			prio=OPERA_PRIO_PLUS_IN;
			break;
		case '-':
			prio=OPERA_PRIO_MINUS_IN;
			break;
		case '*':
			prio=OPERA_PRIO_MULTIPLY_IN;
			break;
		case '/':
			prio=OPERA_PRIO_DIVISION_IN;
			break;
		case '(':
			prio=OPERA_PRIO_LEFT_BRACKETS_IN;
			break;
		default:
			prio=OPERA_PRIO_ERR;
			break;
		}
	}
	else
	{
		switch(opera)
		{
		case '+':
			prio=OPERA_PRIO_PLUS_OUT;
			break;
		case '-':
			prio=OPERA_PRIO_MINUS_OUT;
			break;
		case '*':
			prio=OPERA_PRIO_MULTIPLY_OUT;
			break;
		case '/':
			prio=OPERA_PRIO_DIVISION_OUT;
			break;
		case '(':
			prio=OPERA_PRIO_LEFT_BRACKETS_OUT;
			break;
		case ')':
			prio=OPERA_PRIO_RIGHT_BRACKETS_OUT;
			break;
		default:
			prio=OPERA_PRIO_ERR;
			break;
		}
	}
	return prio;
}

//中缀表达式转为后缀表达式
void MidToLast(const char *mid,char *last)
{
	SNode s;
	InitStack(&s);
	int prioIn;//栈内运算符优先级
	int prioOut;//栈外运算符优先级

	int tmp;
	while(*mid!='\0')
	{
		if(isdigit(*mid))//数字字符直接存放在后缀表达式中
		{
			*last++=*mid++;
		}
		else//运算符
		{
			if(IsEmpty(&s))//栈空,直接进栈
			{
				Push(&s,*mid++);
			}
			else
			{
				prioOut=Priority(*mid,false);
				GetTop(&s,&tmp);
				prioIn=Priority((char)tmp,true);
				if(prioOut<prioIn)//栈外优先级高,入栈
				{
					Push(&s,*mid++);
				}
				else if(prioOut>prioIn)//栈内优先级高,出栈
				{
					Pop(&s,&tmp);
					*last++=(char)tmp;
				}
				else//括号匹配
				{
					mid++;
					Pop(&s,NULL);
				}
			}
		}
	}
	while(!IsEmpty(&s))
	{
		Pop(&s,&tmp);
		*last++=(char)tmp;
	}
	*last='\0';
}


int main()
{
	char *mid="3+4*2/(5-4+1)";
	char last[100];
	MidToLast(mid,last);
	printf("mid=%s\nlast=%s\n",mid,last);

	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值