问题 E: DS栈—波兰式,逆波兰式

问题 E: DS栈—波兰式,逆波兰式
时间限制: 1 Sec 内存限制: 128 MB

题目描述

   表达式有三种表示方法,分别为:

前缀表示(波兰式):运算符+操作数1+操作数2

中缀表示:操作数1+运算符+操作数2

后缀表示(逆波兰式):操作数1+操作数2+运算符

例如:a +b * (c -d ) - e/f

波兰式:-+a*b-cd/ef     (运算符在操作数的前面,用递归计算波兰式)

中缀式:a+b*c-d-e/f  

逆波兰式:abcd-*+ef/   (运算符在操作数的后面,用栈计算逆波兰式)

   中缀表示就是原表达式去掉扣号。       

 根据表达式求波兰式、逆波兰式都是教材第三章表达式求值的思想。     

  求波兰式,需要操作数栈(注意不是计算结果入栈,有计算式入栈),运算符栈。区别在于从后往前扫描表达式,‘(’ 换成')','('换成‘)’。栈顶运算符优先级>新读入运算符优先级出栈,表3.1中的相同运算符优先级>(从左往右计算)改为<,例如栈顶为‘+‘,新读入的为‘+’,则栈顶优先级<新读入的优先级。

 求逆波兰式,只需要运算符栈。操作数直接输出,操作符按表3.1优先级顺序出栈,输出。

   输入表达式,求其波兰式和逆波兰式。

输入

测试次数

每组测试数据一行,一个合法表达式
输出

对每组测试数据,输出两行

第一行,表达式的波兰表示

第二行,表达式的逆波兰表示

不同组测试数据间以空行分隔。

样例输入
2
4+2*3-10/5
12+3*5+(2+10)*5 

样例输出
- + 4 * 2 3 / 10 5
4 2 3 * + 10 5 / -

+ + 12 * 3 5 * + 2 10 5
12 3 5 * + 2 10 + 5 * +

#include<iostream>
#include<stack>
#include<map>
#include<cmath>
#include<string.h>
#include<string>
#include<algorithm>
using namespace std;

stack<char> opre;
stack<int> nums;

bool isbigcmp(char a, char b)
{
	if (a == '+' || a == '-')
	{
		if (b == '(' || b == '#'||b=='*'||b=='/')return false;
		return true;
	}
	else if (a == '*' || a == '/')
	{
		if (b == '(')return false;
		return true;
	}
	else if (a == '(')
	{
		if (b == ')')return true;
		return false;
	}
	else if (a == ')')
	{
		return true;
	}
	else if (a == '#')
	{
		if(b=='#')
		return true;
		return false;
	}
}

bool isbigcmp2(char a, char b)
{
	if (a == '+' || a == '-')
	{
		if (b == '(' || b == '#' || b == '*' || b == '/'||b=='+'||b=='-')return false;
		return true;
	}
	else if (a == '*' || a == '/')
	{
		if (b == '(')return false;
		return true;
	}
	else if (a == '(')
	{
		//if (b == ')')return true;
		return false;
	}
	else if (a == ')')
	{
		return true;
	}
	else if (a == '#')
	{
		//if (b == '#')
		//	return true;
		return false;
	}
}

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		string fn;
		cin >> fn;
		for (int i = fn.length() - 1; i >= 0; i--)
		{
			if ((fn[i] >= 'a' && fn[i] <= 'z') || (fn[i] >= 'A' && fn[i] <= 'Z') || (fn[i] >= '0' && fn[i] <= '9'))
			{
				int tot = fn[i]-'0';
				int x = 10;
				while (i - 1 >= 0 && isdigit(fn[i - 1]))
				{
					tot += x * (fn[i - 1] - '0');
					x *= 10;
					i--;
				}
				nums.push(tot);
			}
			else
			{
				if (opre.empty() || opre.top() == ')' || fn[i] == ')')
				{
					opre.push(fn[i]);
				}
				else if (fn[i] == '(')
				{
					while (opre.top() != ')')
					{
						nums.push(opre.top()*1000000);
						opre.pop();
					}
					//nums.push(opre.top());
					opre.pop();
				}
				else if (isbigcmp(fn[i], opre.top()))
				{
					opre.push(fn[i]);
				}
				else if (!isbigcmp(fn[i], opre.top()))
				{
					while (opre.size() != 0 && !isbigcmp(fn[i], opre.top()))
					{
						nums.push(opre.top()*1000000);
						opre.pop();
					}
					opre.push(fn[i]);
				}
			}
		}
		while (!opre.empty())
		{
			nums.push(opre.top() * 1000000);
			opre.pop();
		}
		while (!nums.empty())
		{
			int x = nums.top();
			if (x > 1000000)
			{
				x /= 1000000;
				cout << (char)x << " ";
			}
			else
			{
				cout << nums.top() << " ";
			}
			nums.pop();
		}
		cout << endl;
		//-----------------------------------------------------------------------------
		for (int i = 0; i < fn.length(); i++)
		{
			if ((fn[i] >= 'a' && fn[i] <= 'z') || (fn[i] >= 'A' && fn[i] <= 'Z') || (fn[i] >= '0' && fn[i] <= '9'))
			{
				int tot = fn[i] - '0';
				while (i + 1 <fn.length() && isdigit(fn[i + 1]))
				{
					tot = tot*10+ (fn[i + 1] - '0');
					i++;
				}
				//nums.push(tot);
				cout << tot << " ";
			}
			else
			{
				if (opre.empty() || opre.top() == '(' || fn[i] == '(')
				{
					opre.push(fn[i]);
				}
				else if (fn[i] == ')')
				{
					while (!opre.empty() && opre.top() != '(')
					{
						//nums.push(opre.top());
						cout << opre.top()<<' ';
						opre.pop();
					}
					//nums.push(opre.top());
					opre.pop();
				}
				else if (isbigcmp2(fn[i], opre.top()))
				{
					opre.push(fn[i]);
				}
				else if (!isbigcmp2(fn[i], opre.top()))
				{
					while (!opre.empty() && !isbigcmp2(fn[i], opre.top())&&opre.top()!='(')
					{
						//nums.push(opre.top());
						cout << opre.top() << ' ';
						opre.pop();
					}
					opre.push(fn[i]);
				}
			}
		}
		while (!opre.empty())
		{
			//nums.push(opre.top());
			cout << opre.top() << " ";
			opre.pop();
		}
		/*while (!nums.empty())
		{
			cout << (char)nums.top()<<" ";
			nums.pop();
		}*/
		cout << endl<<endl;
	}
	return 0;
}



  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值