波兰表达式

28 篇文章 1 订阅
25 篇文章 0 订阅

波兰表达式

标签(空格分隔): 算法竞赛


2694:逆波兰表达式
查看 提交 统计 提示 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4。本题求解逆波兰表达式的值,其中运算符包括+ - * /四个。
输入
输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数。
输出
输出为一行,表达式的值。
可直接用printf("%f\n", v)输出表达式的值v。
样例输入
* + 11.0 12.0 + 24.0 35.0
样例输出
1357.000000
提示
可使用atof(str)把字符串转换为一个double类型的浮点数。atof定义在math.h中。
此题可使用函数递归调用的方法求解。
来源
计算概论05

我写了两次,第一次用栈模拟,TLE了,第二次直接看的答案敲的,办法真是巧妙,代码比我短的多,逻辑也比我清楚,执行时间也比我快得多。。。

先附上我用函数调用栈模拟的代码。长的一塌糊涂,还不好懂。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <stack>
#define N 10000
#define M 30
using namespace std;
int Scan();
char a[N][M];
void Operation(int i);
int JudgeOperator(int n);
stack<double> num;
int main()  {
    int i=0;
    i=Scan();
    Operation(i);
    double ans=num.top(); 
    printf("%f\n",ans);
    return 0;
}
int Scan()  {
    int i=0;
    while (1)   {
        scanf("%s",a[i]);
        if (getchar()=='\n')    break;
        i++;
    }
    return i;
}
void Operation(int n)   {
    if (!JudgeOperator(n))
    {
        double temp=atof(a[n]);
        num.push(temp);
    }
    if (!n) return;
    Operation(--n);
}
int JudgeOperator(int n)    {
    switch(a[n][0]) {
        case '+':   {
            double a=num.top();
            num.pop();
            double b=num.top();
            num.pop();
            double temp=b+a;
            num.push(temp);
            return 1;
            break;
        }
        case '-':   {
            double a=num.top();
            num.pop();
            double b=num.top();
            num.pop();
            double temp=b-a;
            num.push(temp);
            return 1;
            break;
        }
        case '*':   {
            double a=num.top();
            num.pop();
            double b=num.top();
            num.pop();
            double temp=b*a;
            num.push(temp);
            return 1;
            break;
        }
        case '/':   {
            double a=num.top();
            num.pop();
            double b=num.top();
            num.pop();
            double temp=b/a;
            num.push(temp);
            return 1;
            break;
        }
        default:return 0;break;
    }
}

再附上我用答案的方法,纯递归实现

#include <cstdio>
#include <cstdlib>
using namespace std;
double exp()    {
    char str[20];
    scanf("%s",str);
    switch(str[0])  {
        case '+':   return exp()+exp();break;
        case '-':   return exp()-exp();break;
        case '*':   return exp()*exp();break;
        case '/':   return exp()/exp();break;
        default:    return atof(str);break;
    }
}
int main()  {
    double ans=exp();
    printf("%f\n",ans);
    return 0;
} 

呵,显然被完虐了。

看到那个表达式,首先我们会思考,到底是怎么实现的表达式的运算。然后我们会看到,读到运算符时,继续判断下两个是不是数字,如果是,就继续该过程。如果后两个是数字,就依次读入后转化为浮点数,执行前面的运算符所对应的内容。这个过程是递归的,正是因为我没有认识到这一点,才写了这个垃圾代码。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值