栈的应用之前、中、后缀表达式(C++)

本文介绍了算术表达式的求值,包括中缀表达式转后缀表达式、后缀表达式求值、中缀表达式转前缀表达式和前缀表达式求值。通过举例和详细解释说明了如何利用栈进行这些转换和计算,并提供了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、表达式求值

表达式求值是程序设计语言编译的一个最基本的问题。它的实现是栈应用的又一典型例子。仅以算术表达式为例:

1.算术表达式的组成

将表达式视为由操作数、运算符、界限符(称为单词)组成。
【操作数】:常数、变量或符号常量。
【算符】:运算符、界限符。

2.算术表达式的形式

(1)中缀(infix)表达式——表达式的运算符在操作数的中间。即:<操作><操作><操作>
        例1:A*B
        例2:5+9*7

(2)后缀(postfix)算术表达式(逆波兰式)——将运算符置两个操作数后面的算术表达式。即:<操作><操作><操作>
        例1:AB*
        例2:597*+

(3)前缀(prefix)表达式(波兰式)又称波兰式,与后缀表达式相反。把运算符放在两个运算数的前面,即:<操作><操作><操作>
        例:*AB
        例:+5*97

二、算术表达式的求值

【例】
中缀:1+(2-3)*4+4/2
后缀:123-4*+42/+
前缀:++1*-234/42

1、中缀表达式转后缀表达式

我们先讨论中缀表达式如何转后缀表达式,因为中缀表达式有利于人的理解运算,而后缀表达式更便于计算机的处理。
(1)限制考虑 +、-、*、/、() 符号,根据四则运算规则,我们可以得出其优先级(数字越大,优先级越高):
        1:(

        2:+ -

        3:* /

        4:)

对输入的中缀表达式从左到右遍历

(1)如果遇到数字,直接添加到后缀表达式末尾;

(2)如果遇到运算符+、-、*、/:
先判断栈是否为空。若是,则直接将此运算符压入栈。若不是,则查看当前栈顶元素。若栈顶元素优先级大于或等于此操作符级别,则弹出栈顶元素,将栈顶元素添加到后缀表达式中,并继续进行上述判断。如果不满足上述判断或者栈为空,将这个运算符入栈。要注意的是,经过上述步骤,这个运算符最终一定会入栈。

(3)如果遇到括号:
如果是左括号,直接入栈。如果是右括号,弹出栈中第一个左括号前所有的操作符,并将左括号弹出。(右括号别入栈)。

(4)字符串遍历结束后,如果栈不为空,则弹出栈中所有元素,将它们添加到后缀表达式的末尾,直到栈为空。

#include <iostream>
#include <stack>
#include <string> 
using namespace std;

//获取优先级 
int getP(char ch){
   
	if(ch == '(') return 1;
	else if(ch == '+' || ch == '-') return 2;
	else if(ch == '*' || ch == '/') return 3;
	else return 4;
}

//将中缀表达式转化为后缀表达式
//默认输入是合法的 
string getPE(string str){
   
	stack<char> mystack; 
	int size = str.size();
	int i = 0;
	char tmp;
	string res = ""; //存放中缀转化的后缀表达式 
	
	while(i < size){
   
		//数字直接写入后缀 
		if(str[i] >= '0' && str[i] <= '9'){
   
			res += str[i];
		}
		// 处理 + - * / 
		else if(str[i]=='+' || str[i]=='-' || str[i]=='*' || str[i]=='/'){
   
			if(mystack.empty()) mystack.push(str[i]);//如果栈为空,直接入栈 
			
			else{
   
				while(!mystack.empty()){
   
					tmp = mystack.top();
					if(getP(tmp) >= getP(str[i])){
   
						res += tmp;
						mystack.pop();
					}
					else break;
				}
				mystack.push(str[i]);
			}
			
		}
		//处理括号 () 
		else{
   
			if(str[i]=='(') mystack.push(str[i]); //左括号直接入栈 
			else{
   
				while(mystack.top() != '('){
   
					tmp = mystack.top();
					res += tmp;
					mystack.pop();
				}
				mystack.pop();
			} 
		}
		
		i++;
	}
	
	//遍历完后,若栈非空,弹出所有元素 
	while(!mystack.empty()){
   
		tmp 
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值