HDOJ2127:Polish notation——表达式转换

Problem Description
Reverse Polish notation (RPN) is a method for representing expressions in which the operator symbol is placed after the arguments being operated on.
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 5
6
Case 2:
– + 1 * 2 – 3 4 * 5 6
-31

题目考察表达式的转换将中缀表达式转换成前置表达式(波兰式),并计算出结果。可以直接套模板……需要注意表达式中空格的位置;字符串需要用__int64存贮。

关于前置表达式和后置表达式的转换方法可以参考这篇博文:波兰式、逆波兰式与表达式求值

参考代码:

#include 
#include 
#include 
using namespace std;

char stack[500];                    
int top;                        //栈顶指针       
char output[500], input[500];        
int outLen;

int priority(char op)           //定义运算符优先级     
{
    if (op=='+' || op=='-')
        return 1;
    if (op=='*' || op=='/')
        return 2;
    else
        return 0;
}

bool isOperator(char op)                
{
    return (op=='+' || op=='-' || op=='*' || op=='/');
}

void Polish(char *s,int len)            
{
    memset(output,'\0',sizeof output);    
    outLen = 0;
    for (int i=len-1; i >= 0; --i)        
    {
        if (isdigit(s[i]))                
        {
            output[outLen++] = s[i];    
            while (i-1 >= 0 && isdigit(s[i-1]))
            {
                output[outLen++] = s[i-1];
                --i;
            }
            output[outLen++] = ' ';        
        }
        if (s[i]==')')                    
        {
            ++top;
            stack[top] = s[i];
        }
        while (isOperator(s[i]))        
        {                                                
            if (top==0 || stack[top]==')' || priority(s[i]) >= priority(stack[top])) 
            {
                ++top;
                stack[top] = s[i];
                break;
            }
            else
            {
                output[outLen++] = stack[top];
                output[outLen++] = ' ';
                --top;
            }
        }
        if (s[i]=='(')                    
        {
            while (stack[top]!=')')
            {
                output[outLen++] = stack[top];
                output[outLen++] = ' ';
                --top;
            }
            --top;    
        }
    }
    while (top!=0)                        
    {
        output[outLen++] = stack[top];
        output[outLen++] = ' ';
        --top;
    }
}

char DstBuf[200];
char* OP(char* op1,char* op2,char op)
{
    __int64 res = 0;
    if (op=='+')
        res = _atoi64(op1) + _atoi64(op2);
    else if (op=='-')
        res = _atoi64(op1) - _atoi64(op2);
    else if (op=='*')
        res = _atoi64(op1) * _atoi64(op2);
    else if (op=='/')
        res = _atoi64(op1) / _atoi64(op2);
    _i64toa(res,DstBuf,10);
    return DstBuf;
}

char cSt1[200][80], cSt2[200][80];
__int64 calc(char *s)                
{
    int top1=0, top2=0, i;
    for (i=0; s[i]; ++i)
    {
        if (s[i] && s[i] != ' ')
        {
            ++top1;
            sscanf(s+i,"%s",cSt1[top1]);        
            while (s[i] && s[i] != ' ')
                ++i;
        }
    }
    while (top1 != 0)    
    {
        if (!isdigit(cSt1[top1][0]))    
        {
            OP(cSt2[top2], cSt2[top2-1], cSt1[top1][0]);
            memcpy(cSt2[top2-1],DstBuf,sizeof DstBuf);
            --top2;                    
            --top1;                        
        }
        else
        {
            ++top2;                        
            memcpy(cSt2[top2],cSt1[top1],sizeof cSt1[top1]);
            --top1;                        
        }
    }
    return _atoi64(cSt2[1]);
}
int main()
{
    int T = 1;
    while (gets(input))
    {
        Polish(input, strlen(input));
        reverse(output,output+outLen-1);
        output[outLen-1] = '\0';
        printf("Case %d:\n%s\n",T++,output);
        printf("%I64d\n",calc(output));//注意要__int64
    }
    return 0;
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注