SDUT 2132 一般算术表达式转换成后缀式(栈的应用与后缀式的一些概念)

Problem Description

对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之。

Input

输入一个算术表达式,以‘#’字符作为结束标志。

Output

输出该表达式转换所得到的后缀式。

Sample Input

a*b+(c-d/e)*f#

Sample Output

ab*cde/-f*+

先来说明一下后缀式:这是把运算符写在运算对象后边的一种表达式的写法。

相应的,中缀式(正常表达式)变换为后缀式也有一套办法,实际上它就是这个栈的模拟类应用的解法:

1.设定运算符栈

2.假设表达式的结束符为"#",我们需要预设运算符栈底元素为"#"

3.扫描表达式,若当前字符是操作数,则直接发送给后缀表达式;

4.若当前字符为运算符且优先级大于栈顶运算符,则进栈,否则退出栈顶运算符并将其发送给后缀式。然后将当前运算符放入栈中。

5.若当前字符是结束符,则将栈中的全部运算符依次发送给后缀式。

6.若当前字符为"(",进栈。

7.若当前字符为")",则从栈顶起,依次将栈中运算符出栈发送给ie后缀式,直到碰到"("。将栈中"("出栈,不需要发送给后缀式。然后继续扫描表达式。

以上就是整个算法,我们在这里对其进行严格模拟,但是有些小细节也可以优化:

  1. 由于这里的运算对象都是字母,所以直接用isalpha(arguement)判断即可,调用此函数,小写字母会返回2,大写字母返回1,非字母返回0。
  2. 由于*/(乘除)平级,+-(加减)平级(因为是双目运算符,所以这个题只涉及四则运算),所以可以设定一个数组,使这些运算符分别对应一个值(类似于Python的字典),这样就好判断优先级了

所以有如下思路:

  1. 利用已知算法进行模拟 

代码如下:

 

#include<pch.h>
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
#include <map>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <cstring>
#include <cmath>
#define DETERMINATION main
#define lldin(a) scanf_s("%lld", &a)
#define println(a) printf("%lld\n", a)
#define reset(a, b) memset(a, b, sizeof(a))
const int INF = 0x3f3f3f3f;
using namespace std;
const double PI = acos(-1);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int mod = 1000000007;
const int tool_const = 19991126;
const int tool_const2 = 33;
inline ll lldcin()
{
	ll tmp = 0, si = 1;
	char c;
	c = getchar();
	while (c > '9' || c < '0')
	{
		if (c == '-')
			si = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
	{
		tmp = tmp * 10 + c - '0';
		c = getchar();
	}
	return si * tmp;
}
///Untersee Boot IXD2(1942)
/**Although there will be many obstructs ahead,
the desire for victory still fills you with determination..**/
/**Last Remote**/
char input[50000];
ll key[7];
stack<char>sta;
int DETERMINATION()
{
	cin >> input;
	ll len = strlen(input);
	reset(key, 0);
	key['/'] = 4, key['*'] = 4, key['-'] = 2, key['+'] = 2;//优先级设定
	for (int i = 0; i < len; i++)
	{
		if (input[i] == '#')//如果中间有终止符直接停止
			break;
		if (isalpha(input[i]) )//运算对象判断
			cout << input[i];
		else if (key[input[i]])
		{
			if (sta.empty())
				sta.push(input[i]);
			else
			{
				while (sta.empty()==false&&key[input[i]] <= key[sta.top()])//优先级判定
				{
					cout << sta.top();
					sta.pop();
				}
				sta.push(input[i]);
			}
		}
		else if (input[i] == '(')
			sta.push(input[i]);
		else if (input[i] == ')')
		{
			while (sta.top() != '(')
			{
				cout << sta.top();
				sta.pop();
			}
			sta.pop();
		}
	}
	while (sta.empty() == false)
		{
			cout << sta.top();
			sta.pop();
		}
	return 0;
}

 

posted @ 2019-07-28 23:35  完全墨染的樱花  阅读(207)  评论(0)    收藏  举报