【C语言】后缀表达式转换(中缀->后缀)

题目描述
输入一个中缀表达式,编程输出其后缀表达式,要求输出的后缀表达式的运算次序与输入的中缀表达式的运算次序相一致。为简单起见,假设输入的中缀表达式由+(加)、-(减)、×(乘)、/(除)四个运算符号以及左右圆括号和英文字母组成,其中算术运算符遵守先乘除后加减的运算规则。假设输入的中缀表达式长度不超过200个字符,且都是正确的,即没有语法错误,并且凡出现括号其内部一定有表达式,即内部至少有一个运算符号。

输入
只有一行,为中缀表达式

输出
只有一行,为转换后的后缀表达式

样例输入

X+A*(Y-B)-Z/F

样例输出

XAYB-*+ZF/-

解题思路:
建立两个栈,数据总栈与运算符栈,一个存储全部数据,一个作为中间过程需求存储运算符。

  • 遇到数字时,直接入栈->数据总栈
  • 遇到运算符时,操作如下:
    1、若此运算符是式子的第一个运算符或者为’(’ ,直接入栈->运算符栈。
    2、若为’)’ :出栈所有运算符,并入栈->数据总栈,直到遇到 ‘(’,最后将 '('出栈。
    3、若此运算符的优先级大于运算符栈栈顶运算符,则直接入栈->运算符栈,
    否则,运算符栈栈顶运算符出栈,随后入栈->数据总栈。此运算符接替栈顶的位置,再与前一位运算符比较,重复上述操作,直到此运算符的优先级大于前一位运算符。
  • 当数据都操作完后,出栈所有运算符栈的运算符,依次入栈->数据总栈。

代码如下:

#include 

/*符号栈*/
struct Symbol
{
     
	int top;
	char s[400];
}symbol;

/*数据总栈*/
struct Number
{
     
	int top;
	char n[400];
}number;

//栈的初始化
void init()
{
     
	symbol.top = -1;
	number.top = -1;
}

//将运算符替换成数字以比较优先级
/*优先级:【'*'='/'】 > 【'+'='-'】 > 【'('】 */ 
int replace(char a)
{
     
	switch (a)
	{
     
		case '+':return 1;
		case '-':return 1;
		case '*':return 2;
		case '/':return 2;
		case '(':return 0;
	}
}

//优先级的比较
/* s为符号栈的栈顶运算符,e为待定运算符
	若s
int compare(char s, char e)
{
     
	return (replace(s) < replace(e)) ? 1 : 0;
}

//后缀表达式转换
void reversePolish(char ex[])
{
     
	for (int i = 0; ex[i] != '\0'; i++)
	{
     
		/*若字符为A-Z,直接添加到数据总栈*/
		if (ex[i] <= 'Z' && ex[i] >= 'A' || ex[i] <= 'z' && ex[i] >= 'a')
		{
     
			number.n[++number.top] = ex[i];
		}

		else
		{
     
			if (symbol.top == -1) {
      symbol.s[++symbol.top] = ex[i]; continue; }
			if (ex[i] == '(') {
      symbol.s[++symbol.top] = ex[i]; continue; }
			/*若ex[i]为')',则将运算符栈栈顶运算符出栈 添加到数据总栈,直到运算符栈栈顶为')'*/
			if (ex[i] == ')')
			{
     
				while (symbol.s[symbol.top] != '(')
				{
     
					number.n[++number.top] = symbol.s[symbol.top];
					symbol.top--;
				}
				symbol.top--;
				continue;
			}
			
			/*比较运算符栈顶运算符symbol.s[symbol.top],与待定运算符ex[i]的优先级*/
			if (compare(symbol.s[symbol.top], ex[i])) symbol.s[++symbol.top] = ex[i];
			/*若成立,直接将ex[i]添加到符号栈栈顶*/
			/*不成立,先将运算符栈顶运算符出栈,添加到数据总栈,
			然后将ex[i]入运算符栈,再与前一位运算符比较,循环上述操作,
			直到运算符栈顶运算符优先级大于它的前一位运算符*/
			else
			{
     
				number.n[++number.top] = symbol.s[symbol.top];
				symbol.s[symbol.top] = ex[i];
				while (!compare(symbol.s[symbol.top - 1], symbol.s[symbol.top]) && symbol.top > 0)
				{
     
					number.n[++number.top] = symbol.s[symbol.top - 1];
					symbol.s[symbol.top - 1] = symbol.s[symbol.top];
					symbol.top--;
				}
			}
		}
	}
	/*将运算符栈剩余的运算符依次出栈并添加到数据总栈*/
	while (symbol.top != -1)
	{
     
		number.n[++number.top] = symbol.s[symbol.top];
		symbol.top--;
	}
}

//输出结果(后缀表达式)
void printList()
{
     
	for (int i = 0; i <= number.top; i++)
	{
     
		printf("%c", number.n[i]);
	}
}

int main() {
     
	char ex[400];
	init();
	scanf("%s", ex);
	reversePolish(ex);
	printList();

	return 0;
}

你可能感兴趣的:(栈)