编程介的小学生 2019-05-23 00:27 采纳率: 20.5%
浏览 544

一个表达式的四则运算,判断表达式的结果,怎么利用C语言的程序的代码的编写来实现?

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
  • 写回答

1条回答 默认 最新

  • Prime_min 2019-05-23 10:32
    关注

    这是一个基本的表达式计算问题。
    是要输出(逆)波兰表达式

    #include <iostream>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    char stack[500];                    //定义顺序栈,其中top==0表示栈为空;
    int top;                            //栈顶指针,为0表示栈为空;
    char output[500], input[500];       //波兰式
    int outLen;
    
    int priority(char op)               //判断运算符级别函数;其中* /的级别为2,+ -的级别为1;
    {
        if (op=='+' || op=='-')
            return 1;
        if (op=='*' || op=='/')
            return 2;
        else
            return 0;
    }
    
    bool isOperator(char op)                //判断输入串中的字符是不是操作符,如果是返回true
    {
        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)      //1)求输入串的逆序。
        {
            if (isdigit(s[i]))              //经验见:http://blog.csdn.net/linraise/article/details/18566319#comments
            {
                output[outLen++] = s[i];    //3)假如是操作数,把它添加到输出串中。
                while (i-1 >= 0 && isdigit(s[i-1]))
                {
                    output[outLen++] = s[i-1];
                    --i;
                }
                output[outLen++] = ' ';     //空格隔开
            }
            if (s[i]==')')                  //4)假如是闭括号,将它压栈。
            {
                ++top;
                stack[top] = s[i];
            }
            while (isOperator(s[i]))        //5)如果是运算符,执行算法对应操作;
            {                                               //>=很重要
                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]=='(')                  //6)假如是开括号,栈中运算符逐个出栈并输出,直到遇到闭括号。闭括号出栈并丢弃。
            {
                while (stack[top]!=')')
                {
                    output[outLen++] = stack[top];
                    output[outLen++] = ' ';
                    --top;
                }
                --top;  // 此时stack[top]==')',跳过)
            }
            //7)假如输入还未完毕,跳转到步骤2。
        }
        while (top!=0)                      //8)假如输入完毕,栈中剩余的所有操作符出栈并加到输出串中。
        {
            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()
    {
    #ifndef ONLINE_JUDGE
        freopen("2.txt","r",stdin);
    #endif
    
        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));
        }
        return 0;
    }
    

    代码详解来自于

    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)