#ybt1198 逆波兰表达式

南笙酒味 提交于 2020-01-21 16:01:57

ybt1198 逆波兰表达式

题目描述】

逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式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

【题解】

这是一道典型的递归,首先先要读懂题,逆波兰表达式指运算符后面有两项参加运算的数,分析样例,得"+ 11.0 12.0"和"+ 24.0 35.0"分别是"*"的两个因数,要想求积,就要先求出这两个表达式的结果。

已知每个运算符就要调用两个值,这样,就知道在递归中如何调用了:

设f(x)为运算符x的结果,那么对于每个f(x),就有a,b为参与运算的数

则:f(x)=axb

递归的边界条件就是当没有运算符时,直接返回数值。

#include<iostream>
#include<cstdio>
#include<cstring> 
using namespace std;
double ans;
string ch;
int at=0;
double Rd(string x) {//将字符串x转换为浮点数
    int tmp=0,i=0;
    double a=0.00;
    while(x[i]>='0'&&x[i]<='9') {
        a*=10.00;
        a+=x[i]-'0';
        i++;
    }
    i++;//因为有小数点,所以跳过 
    while(x[i]>='0'&&x[i]<='9') {
        tmp++;//记录小数点后的位数
        a*=10.00;
        a+=x[i]-'0';
        i++;
    } 
    for(int j=1;j<=tmp;j++) {
        a/=10.00;//小数点后有几位就除以10的几次方
    }
    return a;
}
double f(char x){
    //cout<<x<<endl;
    double a,b;
    string c;
    cin>>c;
    if(c[0]>='0'&&c[0]<='9') {//分别给a,b赋值
        a=Rd(c);//a为数值
    }
    else {
        a=f(c[0]);//a为表达式
    //  cout<<"a "<<a<<endl;
    }
    cin>>c;
    //cout<<Rd(c);
    if(c[0]>='0'&&c[0]<='9') {//同理
        b=Rd(c);
    }
    else {
        b=f(c[0]);
    //  cout<<"b "<<b<<endl;
    }
    if(x=='+'){
    //  cout<<x<<endl;
        return a+b;
    }
    if(x=='-')
        return a-b;
    if(x=='*')
        return a*b;
    if(x=='/')
        return a/b; 
}
int main() {
    cin>>ch;
    if(ch[0]<'0'||ch[0]>'9')
        ans=f(ch[0]);//递归开始
    else {//应对没有运算符,只输入一个数的情况
        ans=Rd(ch);
    }
    printf("%f\n",ans);
    return 0;
}

终于自己肝出一道题,感动!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!