中缀表达式与后缀、前缀表达式之间的转换

生活中,我们常用的是中缀表达式,但是对于计算机来说,后缀或者前缀表达式更好理解,因为后缀表达式已经消掉了优先级

现在举个列子,将这个中缀表达式 (“3+4*2/(5-4+1)”)转为后缀表达式

第一步,根据优先级加括号
(3 + ((4 * 2)/(((5-4)+1)))
第二步,将运算符挪到括号后面(转前缀表达式就是挪到前面)
(3 ((4 2)(((5 4)-1)+)/)+
第三步,去掉括号
3 4 2
5 4-1+/+
这样就将中缀表达式转换成了后缀表达式

下面是代码实现

(1)运算符的优先级

/******************************************************************************************************
  运算符优先级,数值越小优先级越高
*******************************************************************************************************
#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 

(2)
//获取运算符的优先级

   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';

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值