转逆波兰表达式-OpenJudge[等价表达式]

  • 转逆波兰表达式-OpenJudge[等价表达式]


逆波兰表达式

   题目通过将正常式转化成逆波兰式进行求解,有必要复习逆波兰请自行传送门:逆波兰表达式

  • 思路:

最难的就是一般式转逆波兰啦

先搞清楚优先级:括号 > * > + = -

 定义:一串(New_Equal),逆波兰式

            一栈(Signal)暂存运算符(包括括号)

对输入的一般式从头到尾扫一遍

①遇到“( ” :直接入栈

②数字和字母:直接进入逆波兰式

③“ )”:将括号内符号逐个加入逆波兰式并出栈直到遇到“(  ”,将“(  ” 出栈

④+ or - :在入栈新的+ or - 之前,将“(  ” 之前(或直到空栈)的全部运算符加入逆波兰式,然后再入栈新的+ or -

⑤ * :乘法优先级仅低于括号,所以入栈新的 * 之前,如果之前存在平级的 *  ,出栈并加入波兰式,直到栈空或“(  ”

 

My Puzzle Before :非空下出栈运算符可以理解,但我一直在想为什么遇到“(  ”也要停止出栈运算符,后来想通了,括号是最高优先级,所以括号内的运算式优先运算,如果遇到(1+1)-(1*1),对应于逆波兰就是  1 1 + 1 1 * -,每次出栈终止于“(  ”,直到遇到 “ )”起到了优先处理括号内表达式的作用,隔离开了 -  使之置于最后。

  • 代码:



#include<iostream>	
#include<stack>	
#include<string>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAX_Length 500
//数据结构与算法Mooc(第三章栈与队列5等价表达式)
string Change_Equal(char* Initial_Equal)
{
	int Len = strlen(Initial_Equal);
	stack<char> Signal;
	string New_Equal;
	for (int i = 0; i < Len; i++)
	{
		if (Initial_Equal[i] <= '9'&&Initial_Equal[i] >= '0' || Initial_Equal[i] >= 'a'&&Initial_Equal[i] <= 'z')
			New_Equal += Initial_Equal[i];
		else if (Initial_Equal[i] == '(')	//左括号直接入运算符栈
			Signal.push(Initial_Equal[i]);
		else if (Initial_Equal[i] == ')')
		{
			while (Signal.top()!='(')
			{
				New_Equal += Signal.top();		//括号内的运算符进入波兰式
				Signal.pop();
			}
			Signal.pop();
		}
		else if (Initial_Equal[i] == '+' || Initial_Equal[i] == '-')
		{
			while (!Signal.empty() && Signal.top() != '(')   //入加号减号前把括号内其他运算符加入波兰式
			{
				New_Equal += Signal.top();
				Signal.pop();
			}
			Signal.push(Initial_Equal[i]);		//入加号或减号
		}
		else if (Initial_Equal[i] == '*')
		{
			while (!Signal.empty() && Signal.top() != '('&&Signal.top() == '*')		//等同优先级先进入的乘号加入波兰式
			{
				New_Equal += Signal.top();
				Signal.pop();
			}
			Signal.push(Initial_Equal[i]);		//再入乘号
		}
		else
			continue;
	}
	while (!Signal.empty())		//符号栈不空需要将剩余符号加入波兰式
	{
		New_Equal += Signal.top();
		Signal.pop();
	}

	return New_Equal;
}


int Get_Sum(string Equal)
{
	int Len = Equal.length();
	stack<int> Data;
	for (int i = 0; i < Len; i++)
	{
		if (Equal[i] <= 'z'&&Equal[i] >= 'a')
			Data.push((int)Equal[i]);
		else if (Equal[i] >= '0'&&Equal[i] <= '9')
			Data.push((int)Equal[i] - '0');
		else if (Equal[i] == '*')
		{
			int data1 = Data.top();
			Data.pop();
			int data2 = Data.top();
			Data.pop();
			data1 *= data2;
			Data.push(data1);
		}
		else if (Equal[i] == '+')
		{
			int data1 = Data.top();
			Data.pop();
			int data2 = Data.top();
			Data.pop();
			data2 += data1;
			Data.push(data2);
		}
		else if (Equal[i] == '-')
		{
			int data1 = Data.top();
			Data.pop();
			int data2 = Data.top();
			Data.pop();
			data2 -= data1;
			Data.push(data2);
		}
		else
			continue;
	}
	int Res = Data.top();
	return Res;
}

int main()
{
	char Equal1[MAX_Length];
	char Equal2[MAX_Length];
	int t;
	cin >> t;
	getchar();
	while (t--)
	{
		cin.getline(Equal1, MAX_Length);
		cin.getline(Equal2, MAX_Length);
		string NewEuqal1 = Change_Equal(Equal1);
		string NewEqual2 = Change_Equal(Equal2);
		int Sum1 = Get_Sum(NewEuqal1);
		int Sum2 = Get_Sum(NewEqual2);
		
		if (Sum1 == Sum2)
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值