栈之基于后缀表达式的运算

题目描述

其实呢,这玩意简单啊,把我之前这张图拿过来:

意思就是,利用后缀表达式计算运算符的结果(注意后缀表达式是没有括号的):

分析思路

后缀表达式的优点就是,我们没要记住运算符的优先级,符号进来,直接拿两个数出来运算,在压入栈里面就行。

 这里我做了一个输入正常表达式,然后转换成后缀表达式,然后在计算,注意,表达式之间每一个数字之间,数字与操作符之间是有空格的,主要是方便区分数字。

代码

demo.cpp

#include <cstdio>
#include <cstdlib>
extern "C" {
	#include "linkstack.h"
}

//把中缀变后缀
void transfer_suffix(char infix[],char suffix[],link_stack *p_head) 
{
	int index = 0,cursor = 0;
	while(infix[index] != '\0') {
		char ch = infix[index];
		//判断数字拼接,数字直接输出
		if(ch >= '0' && ch <= '9') {
			while(1) {
				if(infix[index] < '0' || infix[index] > '9') {
					break;
				}
				suffix[cursor++] = infix[index++];
			}
			//数字拼完了之后,后面还有一个空格别忘了
			suffix[cursor++] = ' ';
		}
		//下面所有的部分都要开始入栈出栈操作(这里面都是非数字)
		//上面数字拼接就会把index指针循环到非数字的部分
		if(is_empty(p_head)) {
			//这里不能拿ch来压,把index指向的部分压过来
			push_stack(p_head,infix[index]);
		//下面这部分,就分为(括号入栈,栈顶高优先级出栈,栈顶低优先级进栈
		} else if(!is_empty(p_head) && infix[index] != '\0') {//这里必须把'\0'加进来,上面index可能走到结尾
			char oper_ch = infix[index];
			char top_ch = (char)top_stack(p_head);
			//如果是左括号直接进栈
			if(oper_ch == '(') {
				push_stack(p_head,(int)oper_ch);
			//栈顶优先级高,先出栈在进栈,直到遇到(
			} else if(top_ch == '*' && (oper_ch == '+' || oper_ch == '-')) {
				//这个时候,先出栈,在进栈
				while(top_ch != '(') {
					suffix[cursor++] == top_ch;
					suffix[cursor++] = ' ';
					//先把栈弹出再取栈顶进行判断
					pop_stack(p_head);
					top_ch = (char)top_stack(p_head); 
				}
				//出栈之后,把当前符号入栈
				push_stack(p_head,(int)oper_ch);
			//栈顶优先级低,直接进栈
			} else if((top_ch == '+' || top_ch == '-' || top_ch == '(') && (oper_ch != ')')) {
				//直接进栈
				push_stack(p_head,(int)oper_ch);
			//下面考虑出栈并输出
			} else if (oper_ch == ')') {
				//注意栈顶元素是已经有了
				while(top_ch != '(') {
					suffix[cursor++] = top_ch;
					suffix[cursor++] = ' ';
					pop_stack(p_head);
					top_ch = (char)top_stack(p_head);
				}
				//上面出栈输出之后,把'('出栈
				pop_stack(p_head);
			}
		/*进栈出栈的大if*/
		}
		index++;//整体循环字符串
	/**while大循环结束*/
	}
	//整体循环完毕,把栈里面内容输出
	//栈里面是可能还有符号的
	while(!is_empty(p_head)) {
		suffix[cursor++] = (char) top_stack(p_head);
		suffix[cursor++] = ' ';
		pop_stack(p_head);
	}
}

//开始进行后缀表达式计算
//程序整体结束之后就只会有一个结果在栈里面
void calc_suffix(link_stack *stack,char *suffix)
{
	int index = 0;
	char num_arr[20] = {'\0'};//存放数字的字符串
	int cursor = 0;
	int res = 0;//保存最后的结果集
	while(suffix[index] != '\0') {
		char ch = suffix[index];
		//还是做一个数字拼接,如果是数字直接入栈
		if(ch >= '0' && ch <= '9') {
			cursor = 0;//这个游标设定每次从头开始拼接数字
			while(1) {
				if(suffix[index] < '0' || suffix[index] > '9') {
					num_arr[index] = '\0';//这里必须限定
					break;
				}
				num_arr[cursor++] = suffix[index++];
			}
			//把字符串变成整型
			//atoi把字符串变成整型
			int num = atoi(num_arr);
			push_stack(stack,num);
		} else if(suffix[index] == ' ') {
			index++;//这里很可能会直接指向了一个数值,然后进行下一个循环
		//换句话说index++,要放到else里面
		} else {
			char oper = suffix[index];
			//拿到操作符号进行判定
			if(oper == '*' || oper == '+' || oper == '-') {
				//把栈上面的两个操作数拿过来
				//左右操作数别拿反了,在栈上面是有前后顺序的
				int right_num = top_stack(stack);
				pop_stack(stack);
				int left_num = top_stack(stack);
				pop_stack(stack);
				if(oper == '*') {
					res = left_num * right_num;
				} else if(oper == '+') {
					res = left_num + right_num;
				} else if(oper == '-') {
					res = left_num - right_num;
				}
				//把当前结果集压入到栈里面
				push_stack(stack,res);
			}
			index++;//走到符号部分进行index++往前走
		}
	/**大while循环结束**/
	}
}

int main()
{
	char infix[100] = {'\0'};
	char suffix[100] = {'\0'};
	link_stack *p_head = create_stack();
	while(scanf("%s",infix) != EOF && p_head != NULL) {
		transfer_suffix(infix,suffix,p_head);
		printf("%s\n",suffix);
		calc_suffix(p_head,suffix);
		printf("%d\n",top_stack(p_head));
		pop_stack(p_head);
	}  
	return 0;
}

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后缀表达式也叫逆波兰表达式,它是一种不含括号的表达式,在计算机科学中,常用于计算机程序中表达式的求值。 后缀表达式计算过程可以使用来实现。具体步骤如下: 1. 从左到右扫描后缀表达式,对于每一个数字和运算符进行处理。 2. 如果是数字,则直接将其压入中。 3. 如果是运算符,则从中弹出两个数字进行运算,然后将运算结果压入中。 4. 重复上述步骤,直到扫描完整个后缀表达式。 5. 最后中只剩下一个数字,就是该后缀表达式计算结果。 下面是一个简单的示例: 后缀表达式:3 4 + 5 * 1. 遇到 3,将其压入中。 2. 遇到 4,将其压入中。 3. 遇到 + 运算符,从中弹出两个数字 4 和 3,相加得到 7,将其压入中。 4. 遇到 5,将其压入中。 5. 遇到 * 运算符,从中弹出两个数字 5 和 7,相乘得到 35,将其压入中。 6. 整个后缀表达式扫描完毕,中只剩下一个数字 35,即为该后缀表达式计算结果。 代码实现: ``` def evaluate_postfix(expr): stack = [] for token in expr: if token.isdigit(): stack.append(int(token)) else: b = stack.pop() a = stack.pop() if token == '+': stack.append(a + b) elif token == '-': stack.append(a - b) elif token == '*': stack.append(a * b) elif token == '/': stack.append(a / b) return stack.pop() ``` 其中,expr 是后缀表达式,stack 是一个列表用来模拟。对于每个数字,直接将其转换成整数并压入中;对于每个运算符,则从中弹出两个数字进行运算,并将运算结果压入中。最后,中只剩下一个数字,就是该后缀表达式计算结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值