中缀表达式转化为后缀表达式代码

学习了栈的基本的操作后,我们可以做一个应用案例:中缀表达式转为后缀表达式。

人们所熟悉的表达式写法为中缀表达式,但是计算机喜欢后缀表达式,因为不用管理括号匹配的问题,可以利用栈直接计算。

如 :8 +( 3 – 1 ) * 5 => 8 3 1 – 5 * +

给你一个字符串str:8 +( 3 – 1 ) * 5,将它转化为后缀表达式吧。算法如下:

中缀转后缀算法:

遍历中缀表达式中的数字和符号:

  1. 对于数字:直接输出
  2. 对于符号:
    1. 左括号:进栈 
    2. 运算符号:与栈顶符号进行优先级比较
      1. 若栈顶符号优先级低:此符号进栈  (默认栈顶若是左括号,左括号优先级最低)
      2. 若栈顶符号优先级不低:将栈顶符号弹出并输出,之后进栈
    3. 右括号:将栈顶符号弹出并输出,直到匹配左括号,将左括号和右括号同时舍弃
  3. 遍历结束:将栈中的所有符号弹出并输出

代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1024

// 中缀表达式转后缀表达式案例
// 顺序栈
struct SStack {
	void* data[MAX]; // 维护一个数组 每个元素类型void*
	int m_Size; // 栈的大小
};
typedef void* SeqStack;

//初始化栈
SeqStack init_SeqStack() {
	struct SStack* myStack = malloc(sizeof(struct SStack));
	if (myStack == NULL) {
		return NULL;
	}
	memset(myStack->data, 0, sizeof(void*) * MAX); // 数组清空
	myStack->m_Size = 0;
	return myStack;
}
// 入栈
void push_SeqStack(SeqStack stack, void* data) {
	//入栈本质 数组尾插
	if (stack == NULL) {
		return;
	}
	if (data == NULL) {
		return;
	}
	struct SStack* mystack = stack;
	if (mystack->m_Size == MAX) {
		return;
	}
	mystack->data[mystack->m_Size] = data;
	mystack->m_Size++;
}
// 出栈
void pop_SeqStack(SeqStack stack) {
	//出栈本质 尾删
	if (stack == NULL) {
		return;
	}
	struct SStack* mystack = stack;
	if (mystack->m_Size == 0) {
		return;
	}
	mystack->data[mystack->m_Size - 1] = NULL; //逻辑删除
	mystack->m_Size--;
}
// 返回栈顶
void* top_SeqStack(SeqStack stack) {
	if (stack == NULL) {
		return NULL;
	}
	struct SStack* mystack = stack;
	if (mystack->m_Size == 0) {
		return NULL;
	}
	return mystack->data[mystack->m_Size - 1];
}
// 返回栈的大小
int size_SeqStack(SeqStack stack) {
	if (stack == NULL) {
		return -1;
	}
	struct SStack* mystack = stack;
	return mystack->m_Size;
}
// 判断栈是否为空
int isEmpty_SeqStack(SeqStack stack) {
	if (stack == NULL) {
		return -1; //代表真--- 空栈
	}
	struct SStack* mystack = stack;
	if (mystack->m_Size == 0) {
		return 1;
	}
	return 0; // 代表不是空栈
}
// 销毁栈
void destroy_SeqStack(SeqStack stack) {
	if (stack == NULL) {
		return;
	}
	free(stack);
	stack = NULL;
}

//判断是否为数字
int isNumber(char ch) {
	if ('0' <= ch && ch <= '9') {
		return 1;
	}
	else
		return 0;
}

// 优先级确认函数
int priority(char ch) {
	int pri = 0;
	if (ch == '*' || ch == '/')
		pri = 2;
	if (ch == '+' || ch == '-')
		pri = 1;
	if (ch == '(')
		pri = 0;
	return pri;
}


int main() {

	char* str = "8+(3-1)*5"; // 中缀表达式
	char* p = str;
	char dst[MAX] = { 0 };
	int i = 0;

	// 初始化栈
	SeqStack mystack = init_SeqStack();
	while (*p) {
		// 先判断是否为数字
		if (isNumber(*p)) {
			dst[i] = *p;
			i++;
		}
		// 如果为符号
		else {
			//如果是左括号
			if (*p == '(') {
				push_SeqStack(mystack, p);
			}
			else if (size_SeqStack(mystack) > 0) {
				// 栈中有元素,需要进行优先级比较
				// 分为两种情况:
				// 右括号*****************************
				if (*p == ')') {
					//将栈顶元素弹出,直到匹配到左括号;并将左括号与右括号同时舍弃
					while (*(char*)(top_SeqStack(mystack)) != '(') {
						dst[i] = *(char*)(top_SeqStack(mystack));
						pop_SeqStack(mystack);
						i++;
					}
					// 遇到左括号 弹出
					pop_SeqStack(mystack);
				}
				
				// 栈顶优先级符号高
				else if (priority(*(char*)(top_SeqStack(mystack))) > priority(*p)) {
					//将栈顶符号弹出 并输出 再入栈
					dst[i] = *(char*)(top_SeqStack(mystack));
					pop_SeqStack(mystack);
					push_SeqStack(mystack, p);
					i++;
				}
				else {
					push_SeqStack(mystack, p);
				}
			}
			else
				// 不是数字的第一个字符 入栈
				push_SeqStack(mystack, p);	
		}
		p++;
	}
	// 遍历结束 将栈中所有符号弹出并输出
	while (isEmpty_SeqStack(mystack) == 0) {
		// 栈不为空
		dst[i] = *(char*)(top_SeqStack(mystack));
		pop_SeqStack(mystack);
		i++;
	}
	
	// 打印字符串
	printf("%s\n", dst);

	// 销毁栈
	destroy_SeqStack(mystack);
	mystack = NULL;

	system("pause");
	return 0;
}

程序运行结果:

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值