波兰表达式和逆波兰表达式

波兰表达式和逆波兰表达式

今天zxy的实验内容是关于逆波兰表达式的计算,刚好最近在做关于数据结构的习题,于是想着对波兰表达式和逆波兰表达式的转化和运算分别进行一个学习,于是写了这篇博客(有错的地方欢迎大家指出。)

常见的运算表达式,我们一般称为中缀表达式,例如:

5 + ( 6 - 4 / 2 ) * 3

波兰表达式

波兰表达式子我们也称作前缀表达式,就是对中缀表达式进行如下的操作:

首先建立两个栈,一个栈s1用于落实我们最后得到的前缀表达式,一个栈s2用于暂存表达式中的运算符。

对中缀表达式从右向左进行遍历:

如果是数字:则直接压入栈s1。

如果是括号:分为两种情况,如果是右括号,则直接压入栈s2;如果是左括号,我们将栈s2中的运算符依次弹栈到栈s1,直到s1栈顶元素为右括号,将右括号弹栈,结束。

如果是其他运算符:将此时s2栈顶运算符的优先级与该运算符进行比较。如果s2栈顶操作符优先级大于该运算符优先级,则s2弹栈加入到栈s1中,直到s2栈顶操作符优先度小于等于该运算符优先级,将当前运算符压入栈s2中。

遍历完整个中缀表达式后,检测栈s2是否为空。如果不为空,则将s2中的运算符依次弹栈,压入栈s1中。

最后将栈s1中的元素依次弹出(反序输出),得到的即是前缀表达式。

模拟过程:

在这里插入图片描述

代码实现:

#include<iostream>
#include<cctype>
#include<stack>
#include<map>
using namespace std;
stack<char>s1,s2;//s1表示存放波兰表达式的栈,s2用于暂存运算符 
map<char,int>ch_level;//用于建立运算符到优先级的映射 
string s;
void BL(int x){
   //转化递归函数 
	if (x<0) return;//递归结束 
	if (isdigit(s[x])) {
   s1.push(s[x]); BL(x-1);}//如果是数字直接进栈s1 
	else if (s[x]==')'){
   s2.push(s[x]); BL(x-1);}//右括号直接进栈s2
	//遍历到左括号,将栈s2中右括号之上的运算符全部压入栈s1中
	//需要注意的是,由于我们可以确定此时栈中必然存在一个右括号,所以在while中不用判断栈是否为空 
	else if (s[x]=='('){
   while (s2.top()!=')'){
   s1.push(s2.top()); s2.pop();} s2.pop();BL(x-1);}
	else {
   //如果是其他运算符,就对优先级进行比较,这里需要判断栈是否为空 
		while (!s2.empty()&&ch_level[s[x]]>ch_level[s2.top()]){
   s1.push(s2.top()); s2.pop();}
		s2.push(s[x]); BL(x-1); 
	}
}
int main(){
   
	ch_level['/']=1;ch_level['*']=1;ch_level['%']=1;//这三个的优先级比+和-高 
	ch_level['+']=2;ch_level['-']=2;ch_level['(']=3;ch_level[')']=3;
	//括号的优先级确实应该是最高的,但是我在观察流程的时候,发现括号是不参与运算符的比较的
	//所以我默认括号的运算符等级最低 
	cin>>s; BL(s.size()-1);
	whi
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,以下是一个使用C++语言计算中缀表达式波兰表达式逆波兰表达式的示例代码: ```cpp #include <iostream> #includestack> #include <string> using namespace std; // 操作符优先级 int getPriority(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') return 2; return 0; } // 将中缀表达式转换为逆波兰表达式 string infixToRPN(string infix) { string rpn; stack<char> operators; for (char c : infix) { if (isdigit(c)) { rpn += c; } else if (c == '(') { operators.push(c); } else if (c == ')') { while (!operators.empty() && operators.top() != '(') { rpn += operators.top(); operators.pop(); } operators.pop(); // 弹出左括号 } else { while (!operators.empty() && getPriority(operators.top()) >= getPriority(c)) { rpn += operators.top(); operators.pop(); } operators.push(c); } } while (!operators.empty()) { rpn += operators.top(); operators.pop(); } return rpn; } // 计算逆波兰表达式 int evaluateRPN(string rpn) { stack<int> operands; for (char c : rpn) { if (isdigit(c)) { operands.push(c - '0'); } else { int operand2 = operands.top(); operands.pop(); int operand1 = operands.top(); operands.pop(); switch (c) { case '+': operands.push(operand1 + operand2); break; case '-': operands.push(operand1 - operand2); break; case '*': operands.push(operand1 * operand2); break; case '/': operands.push(operand1 / operand2); break; } } } return operands.top(); } int main() { string infixExpression; cout << "请输入中缀表达式:"; cin >> infixExpression; string rpnExpression = infixToRPN(infixExpression); cout << "逆波兰表达式:" << rpnExpression << endl; int result = evaluateRPN(rpnExpression); cout << "计算结果:" << result << endl; return 0; } ``` 你可以将中缀表达式输入到程序中,然后它将输出逆波兰表达式和计算结果。请确保输入的中缀表达式是合法的,并且操作符使用括号明确优先级。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值