中缀表达式转换为后缀表达式(C语言代码+详解)

中缀表达式转换为后缀表达式(思路)

1.创建栈
2.从左向右顺序获取中缀表达式

a.数字直接输出
b.运算符
情况一:遇到左括号直接入栈,遇到右括号将栈中左括号之后入栈的运算符全部弹栈输出,同时左括号出栈但是不输出

情况二:遇到乘号和除号直接入栈,直到遇到优先级比它更低的运算符,依次弹栈。

情况三:遇到加号和减号,如果此时栈空,则直接入栈,否则,将栈中优先级高的运算符依次弹栈(注意:加号和减号属于同一个优先级,所以也依次弹栈)直到栈空或则遇到左括号为止,停止弹栈。(因为左括号要匹配右括号时才弹出)。

情况四:获取完后,将栈中剩余的运算符号依次弹栈输出

例:比如将:2*(9+6/3-5)+4转化为后缀表达式 2 9 6 3 / +5 - * 4 +

在这里插入图片描述
转换算法代码如下:

/*中缀转后缀函数*/
void Change(SqStack *S,Elemtype str[])
{
	int i=0;
	Elemtype e;
	InitStack(S);
	while(str[i]!='\0')
	{
		while(isdigit(str[i])) 
		{/*过滤数字字符,直接输出,直到下一位不是数字字符打印空格跳出循环 */
			printf("%c",str[i++]);
			if(!isdigit(str[i]))
			{
				printf(" ");
			}
		}
		/*加减运算符优先级最低,如果栈顶元素为空则直接入栈,否则将栈中存储
		的运算符全部弹栈,如果遇到左括号则停止,将弹出的左括号从新压栈,因为左
		括号要和又括号匹配时弹出,这个后面单独讨论。弹出后将优先级低的运算符压入栈中*/
		if(str[i]=='+'||str[i]=='-')
		{
			if(!StackLength(S))
			{
				PushStack(S,str[i]);
			}
			else
			{
				do
				{
					PopStack(S,&e);
					if(e=='(')
					{
						PushStack(S,e);
					}
					else
					{
						printf("%c ",e);
					}
				}while( StackLength(S) && e != '(' );
				
				PushStack(S,str[i]);
			}
		}
		/*当遇到右括号是,把括号里剩余的运算符弹出,直到匹配到左括号为止
		左括号只弹出不打印(右括号也不压栈)*/
		else if(str[i]==')')
		{
			PopStack(S,&e);
			while(e!='(')
			{
				printf("%c ",e);
				PopStack(S,&e);
			}
		}
		/*乘、除、左括号都是优先级高的,直接压栈*/
		else if(str[i]=='*'||str[i]=='/'||str[i]=='(')
		{
			PushStack(S,str[i]);
		}
		
		else if(str[i]=='\0')
		{
			break;
		}
		
		else
		{
			printf("\n输入格式错误!\n");
			return ;
		}
		i++;
	}
	/*最后把栈中剩余的运算符依次弹栈打印*/
	while(StackLength(S))
	{
		PopStack(S,&e);
		printf("%c ",e);
	}
}

完整代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h> 
#include<assert.h>

#define INITSIZE  20
#define INCREMENT 10
#define MAXBUFFER 20
#define LEN  sizeof(Elemtype)

/*栈的动态分配存储结构*/ 
typedef char Elemtype;
typedef struct{
	Elemtype *base;
	Elemtype *top;
	int StackSize;
}SqStack;

/*初始化栈*/
void InitStack(SqStack *S)
{
	S->base=(Elemtype*)malloc(LEN*INITSIZE);
	assert(S->base !=NULL);
	S->top=S->base;
	S->StackSize=INITSIZE;
}

/*压栈操作*/ 
void PushStack(SqStack *S,Elemtype c)
{
	if(S->top - S->base >= S->StackSize)
	{
		S->base=(Elemtype*)realloc(S->base,LEN*(S->StackSize+INCREMENT));
		assert(S->base !=NULL);
		S->top =S->base+S->StackSize;
		S->StackSize+=INCREMENT;
	}
	*S->top++ = c;
}
/*求栈长*/
int StackLength(SqStack *S)
{
	return (S->top - S->base);
}
/*弹栈操作*/
int PopStack(SqStack *S,Elemtype *c)
{
	if(!StackLength(S))
	{
		return 0;
	}
	*c=*--S->top;
	return 1;
}

/*中缀转后缀函数*/
void Change(SqStack *S,Elemtype str[])
{
	int i=0;
	Elemtype e;
	InitStack(S);
	while(str[i]!='\0')
	{
		while(isdigit(str[i])) 
		{/*过滤数字字符,直接输出,直到下一位不是数字字符打印空格跳出循环 */
			printf("%c",str[i++]);
			if(!isdigit(str[i]))
			{
				printf(" ");
			}
		}
		/*加减运算符优先级最低,如果栈顶元素为空则直接入栈,否则将栈中存储
		的运算符全部弹栈,如果遇到左括号则停止,将弹出的左括号从新压栈,因为左
		括号要和又括号匹配时弹出,这个后面单独讨论。弹出后将优先级低的运算符压入栈中*/
		if(str[i]=='+'||str[i]=='-')
		{
			if(!StackLength(S))
			{
				PushStack(S,str[i]);
			}
			else
			{
				do
				{
					PopStack(S,&e);
					if(e=='(')
					{
						PushStack(S,e);
					}
					else
					{
						printf("%c ",e);
					}
				}while( StackLength(S) && e != '(' );
				
				PushStack(S,str[i]);
			}
		}
		/*当遇到右括号是,把括号里剩余的运算符弹出,直到匹配到左括号为止
		左括号只弹出不打印(右括号也不压栈)*/
		else if(str[i]==')')
		{
			PopStack(S,&e);
			while(e!='(')
			{
				printf("%c ",e);
				PopStack(S,&e);
			}
		}
		/*乘、除、左括号都是优先级高的,直接压栈*/
		else if(str[i]=='*'||str[i]=='/'||str[i]=='(')
		{
			PushStack(S,str[i]);
		}
		
		else if(str[i]=='\0')
		{
			break;
		}
		
		else
		{
			printf("\n输入格式错误!\n");
			return ;
		}
		i++;
	}
	/*最后把栈中剩余的运算符依次弹栈打印*/
	while(StackLength(S))
	{
		PopStack(S,&e);
		printf("%c ",e);
	}
}

int main()
{
	Elemtype str[MAXBUFFER];
	SqStack S;
	gets(str);
	Change(&S,str);
	return 0;
}

运行效果截图如下:
在这里插入图片描述

如何实现将中缀表达式转换成后缀表达式后计算值

(https://blog.csdn.net/qq_42552533/article/details/86562791)

  • 163
    点赞
  • 754
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
中缀表达式转换后缀表达式的算法可以使用栈来实现,以下是基本的 C 语言代码实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SIZE 100 // 定义运算符栈结构体 typedef struct operator_stack { char data[MAX_SIZE]; // 栈数据 int top; // 栈顶指针 } OperatorStack; // 定义操作数栈结构体 typedef struct operand_stack { int data[MAX_SIZE]; // 栈数据 int top; // 栈顶指针 } OperandStack; // 判断字符是否为运算符 int is_operator(char c) { return (c == '+' || c == '-' || c == '*' || c == '/'); } // 获取运算符优先级 int get_priority(char c) { int priority = 0; switch (c) { case '+': case '-': priority = 1; break; case '*': case '/': priority = 2; break; default: break; } return priority; } // 运算符栈入栈 void push_operator(OperatorStack *stack, char c) { if (stack->top >= MAX_SIZE) { printf("Operator stack overflow.\n"); exit(1); } stack->data[++stack->top] = c; } // 运算符栈出栈 char pop_operator(OperatorStack *stack) { if (stack->top < 0) { printf("Operator stack underflow.\n"); exit(1); } return stack->data[stack->top--]; } // 获取运算符栈栈顶元素 char get_top_operator(OperatorStack *stack) { if (stack->top < 0) { printf("Operator stack underflow.\n"); exit(1); } return stack->data[stack->top]; } // 操作数栈入栈 void push_operand(OperandStack *stack, int num) { if (stack->top >= MAX_SIZE) { printf("Operand stack overflow.\n"); exit(1); } stack->data[++stack->top] = num; } // 操作数栈出栈 int pop_operand(OperandStack *stack) { if (stack->top < 0) { printf("Operand stack underflow.\n"); exit(1); } return stack->data[stack->top--]; } // 中缀表达式转后缀表达式 void infix_to_postfix(char *infix, char *postfix) { OperatorStack operator_stack; // 运算符栈 OperandStack operand_stack; // 操作数栈 int i, num, len; char c, top_operator, *p; len = strlen(infix); operator_stack.top = -1; operand_stack.top = -1; p = infix; while (*p != '\0') { if (isdigit(*p)) { // 如果是数字,将其入操作数栈 num = 0; while (isdigit(*p)) { num = num * 10 + (*p - '0'); p++; } push_operand(&operand_stack, num); } else if (is_operator(*p)) { // 如果是运算符,将其入运算符栈 while (operator_stack.top >= 0 && get_priority(get_top_operator(&operator_stack)) >= get_priority(*p)) { // 如果当前运算符优先级小于等于栈顶运算符优先级,将栈顶运算符出栈并加入后缀表达式中 top_operator = pop_operator(&operator_stack); postfix[strlen(postfix)] = top_operator; postfix[strlen(postfix)] = ' '; } push_operator(&operator_stack, *p); p++; } else if (*p == '(') { // 如果是左括号,将其入运算符栈 push_operator(&operator_stack, *p); p++; } else if (*p == ')') { // 如果是右括号,将栈内左括号之后的运算符出栈并加入后缀表达式中,左括号出栈 while (operator_stack.top >= 0 && get_top_operator(&operator_stack) != '(') { top_operator = pop_operator(&operator_stack); postfix[strlen(postfix)] = top_operator; postfix[strlen(postfix)] = ' '; } if (operator_stack.top >= 0 && get_top_operator(&operator_stack) == '(') { pop_operator(&operator_stack); } p++; } else { // 如果是空格或其他字符,跳过 p++; } } // 将运算符栈中的运算符出栈并加入后缀表达式中 while (operator_stack.top >= 0) { top_operator = pop_operator(&operator_stack); postfix[strlen(postfix)] = top_operator; postfix[strlen(postfix)] = ' '; } // 将操作数栈中的操作数出栈并加入后缀表达式中 while (operand_stack.top >= 0) { num = pop_operand(&operand_stack); sprintf(postfix + strlen(postfix), "%d ", num); } } int main() { char infix[MAX_SIZE], postfix[MAX_SIZE]; printf("Enter the infix expression: "); fgets(infix, MAX_SIZE, stdin); infix[strlen(infix) - 1] = '\0'; // 去掉输入字符串的换行符 infix_to_postfix(infix, postfix); printf("Postfix expression: %s\n", postfix); return 0; } ```
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值