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
Sample Output
荒废已久的博客,更一更。。
==============================================
引用:
2. 从右至左扫描中缀表达式;
3. 遇到操作数时,将其压入S2;
4. 遇到运算符时,比较其与S1栈顶运算符的优先级:
- 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;
- 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;
- 否则,将S1栈顶的运算符弹出并压入到S2中,再与S1中新的栈顶运算符相比较;
- 如果是右括号“)”,则直接压入S1;
- 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号 丢弃;
7. 将S1中剩余的运算符依次弹出并压入S2;
8. 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。
扫描到的元素 | S2(栈底->栈顶) | S1 (栈底->栈顶) | 说明 |
6 | 6 | 空 | 数字直接入栈 |
* | 6 | * | S1为空,运算符直接入栈 |
5 | 65 | * | 数字直接入栈 |
- | 65* | - | 优先级小于栈顶元素 |
) | 65* | -) | 右括号直接入栈 |
4 | 654* | -) | 数字直接入栈 |
+ | 654* | -)+ | S1栈顶是右括号,直接入栈 |
3 | 6543* | -)+ | 数字直接入栈 |
( | 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;
}