中缀表达式转后缀表达式

80 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情

1、思路

中缀表达式就是我们常用的表达式的形式如 1+2*(8-5)-4/2,我们自己是可以一眼看出先算括号里的,然后是乘除优先于加减计算。但是计算机不行,我们需要把中缀表达式转化成后缀表达式让计算机去计算。

(1)初始化算符栈S,将结束符‘#’压入栈S中

(2)从中缀表达式中读入字符给w

(3)当栈顶为‘#’并且w也是‘#’时结束;否则循环以下步骤:

(3-1)如果w是操作符,直接把它给后缀表达式,读取下一个字符,转到步骤(3)

(3-2-1)如果栈顶为右括号'('并且w为左括号')',就出栈且不把出栈元素给后缀表达式,然后读取下一个字符,之后转到步骤(3)

(3-2-2)如果栈顶为右括号'('或者栈顶优先级小于w的优先级,则w入栈,读取下一个字符,转到步骤(3),否则从栈出栈给到后缀表达式。

2、代码解析

//中缀表达式转后缀表达式
//设置优先级,数字大的优先级高
int priority(char op)
{
	switch (op)
	{
	case '#':return 1; break;//1级
	case ')':return 2; break;//2级
	case '+':
	case '-':return 3; break;//3级
	case '*':
	case '/':return 4; break;//4级
	case '(':return 5; break;//5级
	default:
		return 0;
		break;
	}
}
int infix_exp_value(char * infixexp, char * postfixexp)//infixexp中缀   postfixexp后缀
{
	PSeqStack S;//这个栈是用装符号的栈,用于解决优先级的问题
	char c, w, topelement;//c永远是栈顶元素
	S = Init_SeqStack();
	if (!S)
	{
		//pritnf("栈初始化失败!");
		return 0;
	}
	Push_SeqStack(S, '#');//这才入一个
	w = *infixexp;//w是字符,不是指针??
	while ((GetTop_SeqStack(S, &c), c) != '#' || w != '#')//栈顶元素返回给c   逗号表达式
	{
		if (IsNum(w))//如果是数字,就直接给到字符串
		{
			*postfixexp = w;
			postfixexp++;
			w = *(++infixexp);//读取下一个字符
		}
		else//如果w符号
		{
			if ((GetTop_SeqStack(S, &c), c) == '('&&w == ')')//去括号,得到的w是算符,且发生‘(’ 和‘)’的匹配,就把括号中的字符给到后缀表达式的字符串
			{
				Pop_SeqStack(S, &topelement);//用toplement吸收掉‘(’
				w = *(++infixexp);//读取下一个字符
			}
			else//如果读的w是算符,且不发生‘(’ 和‘)’的匹配
			{
				//
				if ((GetTop_SeqStack(S, &c), c) == '(' || priority((GetTop_SeqStack(S, &c), c)) < priority(w))
				{//翻译:如果栈顶元素是'('或者栈顶元素的优先级小于当前字符,就把w压入栈内,然后读取下一个字符
					Push_SeqStack(S, w);
					w = *(++infixexp);
				}
				else
				{
					Pop_SeqStack(S, &topelement);//出栈
					*postfixexp = topelement;
					postfixexp++;
				}
			}
		}
	}
	*postfixexp = '#';
	*(++postfixexp) = '\0';//结果就直接是值传递给了postfixexp 他是一个char *postfixexp
	Destroy_SeqStack(&S);
	return 1;
}
//中缀转后缀测试
void test03()
{
	char *infixexp = "(4*5)-8/2#";
	char *postfixexp;
	postfixexp = (char*)malloc(sizeof(char));
	infix_exp_value(infixexp, postfixexp);
	puts(postfixexp);
	printf("%.2f", postfix_exp(postfixexp));
}

3、用例测试结果

char *infixexp = "(4*5)-8/2#";

image.png