Polish notation

3 篇文章 0 订阅

Polish notation


Reverse Polish notation (RPN) is a method for representing expressions in which the operator symbol is placed after the arguments being operated on. 
Description

Polish notation, in which the operator comes before the operands, was invented in the 1920s by the Polish mathematician Jan Lucasiewicz. 
In the late 1950s, Australian philosopher and computer scientist Charles L. Hamblin suggested placing the operator after the operands and hence created reverse polish notation. 

RPN has the property that brackets are not required to represent the order of evaluation or grouping of the terms. 
RPN expressions are simply evaluated from left to right and this greatly simplifies the computation of the expression within computer programs. 
As an example, the arithmetic expression (3+4)*5 can be expressed in RPN as 3 4 + 5 *. 

Reverse Polish notation, also known as postfix notation, contrasts with the infix notation of standard arithmetic expressions in which the operator symbol appears between the operands. So Polish notation just as prefix notation.

Now, give you a string of standard arithmetic expressions, please tell me the Polish notation and the value of expressions.

Input

There're have multi-case. Every case put in one line, the expressions just contain some positive integers(all less than 100, the number of integers less than 20), bi-operand operators(only have 3 kinds : +,-,*) and some brackets'(',')'.
you can assume the expressions was valid.

Output

Each case output the Polish notation in first line, and the result of expressions was output in second line.
all of the answers are no any spaces and blank line.the answer will be not exceed the 64-signed integer.

Sample Input
1+2-3*(4-5)1+2*(3-4)-5*6
Sample Output
Case 1:- + 1 2 * 3 - 4 56Case 2:- + 1 * 2 - 3 4 * 5 6-31


荒废已久的博客,更一更。。

==============================================

引用:

由中缀表达式转为前缀表达式的步骤
1. 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
2.  从右至左扫描中缀表达式;
3. 遇到操作数时,将其压入S2;
4. 遇到运算符时,比较其与S1栈顶运算符的优先级:
  • 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;
  • 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;
  • 否则,将S1栈顶的运算符弹出并压入到S2中,再与S1中新的栈顶运算符相比较;
5. 遇到括号时:
  •   如果是右括号“)”,则直接压入S1;
  •  如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号 丢弃;
6. 重复步骤2至5,直到表达式的最左边;
7. 将S1中剩余的运算符依次弹出并压入S2;
8. 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。
     例如,将中缀表达式“(3+4)-5*9”转换为前缀表达式的过程如下:
扫描到的元素S2(栈底->栈顶)S1 (栈底->栈顶)说明
66数字直接入栈
*6*S1为空,运算符直接入栈
565*数字直接入栈
-65*-优先级小于栈顶元素
)65*-)右括号直接入栈
4654*-)数字直接入栈
+654*-)+S1栈顶是右括号,直接入栈
36543*-)+数字直接入栈
(6543*+-左括号,弹出运算符直至遇到右括号
到达最左端6543*+-S1中剩余的运算符

=========================================================


自己写,已ac

#include<stdio.h>
#include<cstdlib>                              
#include<stack>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define MAX 100
long long int operate(long long int n1, long long int n2, char c);
int priorityCompare(char op);
bool Operator(char c);
int index = 0;

int charToint(char str[], int n)
{
	int ans = 0;
	for (int i = n; i >= 0; i--) {
		if (str[i] >= '0' && str[i] <= '9')
			ans += pow(10, n - i) * (str[i] - 48);
		else
			break;
	}
	return ans;
}

void Polish(char str[])
{
	stack<char> s1;
	stack<long long int> s2;//运算结果栈
	stack<int> s3;//前缀表达式栈


	while (!s1.empty())
		s1.pop(); //栈不为空,出栈;
	while (!s2.empty())
		s2.pop();
	while (!s3.empty())
		s3.pop();

	int len;
	len = strlen(str);

	for (int i = len - 1; i >= 0; --i) //从右到左扫描
	{
		if (str[i] >= '0'&&str[i] <= '9') //判断是不是数字
		{
			int num = charToint(str, i);
			s2.push(num); //将字符转换成整型 进入数字栈

			while (i >= 0 && str[i] >= '0' && str[i] <= '9') {
				s3.push(str[i]); //进入前缀表达式栈
				i--;
			}
			i++;
			s3.push(' ');
		}
		if (str[i] == ')')
		{
			s1.push(str[i]);
		}
		if (str[i] == '(')
		{
			char tempChar;//中间变量
						  /*依次弹出栈顶元素,直到遇到右括号*/
			while ((tempChar = s1.top()) != ')')
			{
				s3.push(tempChar); //进表达式栈
				s3.push(' ');

				long long int a = s2.top();
				s2.pop();
				long long int b = s2.top();
				s2.pop();
				s2.push(operate(a, b, tempChar));
				s1.pop();
			}
			if (s1.top() == ')')
			{
				s1.pop();
				continue;
			}
		}
		while (Operator(str[i]))
		{
			if (s1.empty() || s1.top() == ')' || priorityCompare(str[i]) >= priorityCompare(s1.top())) //为空,右括号,srt[i]优先级高
			{
				s1.push(str[i]);
				break;
			}
			else
			{
				s3.push(s1.top());
				s3.push(' ');

				long long int a = s2.top();
				s2.pop();
				long long int b = s2.top();
				s2.pop();
				char c = s1.top();
				s1.pop();
				s2.push(operate(a, b, c));
			}
		}

	}

	while (!s1.empty())
	{
		
		char temp;
		temp = s1.top();
		s3.push(temp);
		s3.push(' ');

		long long int a = s2.top();
		s2.pop();
		long long int b = s2.top();
		s2.pop();

		s2.push(operate(a, b, temp));

		s1.pop();

	}
	s3.pop();
	printf("Case %d:\n", index);
	while (!s3.empty())
	{
		if (s3.top() < 10 && s3.top() != ' ') {
			printf("%d", s3.top());
		}
		else
			printf("%c", s3.top());
		s3.pop();
	}
	printf("\n");
	long long int result;
	result = s2.top();
	printf("%lld\n", result);
}

bool Operator(char c)
{
	return (c == '+' || c == '-' || c == '*' || c == '/');
}


long long int operate(long long int n1, long long int n2, char c)
{
	switch (c)
	{
	case '+':
		return n1 + n2;
	case'-':
		return n1 - n2;
	case'*':
		return n1 * n2;
	case'/':
		if (n2 == 0) printf("ERROR");
		return n1 / n2;
	default:
		return 0;
	}
}

int priorityCompare(char op)
{
	if (op == '+' || op == '-')
		return 1;
	if (op == '*' || op == '/')
		return 2;
	else
		return 0;
}

int main()
{
	char str[MAX];
	while ((cin >> str) && str != NULL) {
		index++;
		Polish(str);
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值