百练 四则运算表达式求值

总时间限制: 
1000ms
内存限制: 
65536kB
描述

求一个可以带括号的小学算术四则运算表达式的值

输入
一行,一个四则运算表达式。'*'表示乘法,'/'表示除法
输出
一行,该表达式的值,保留小数点后面两位
样例输入
输入样例1:
3.4
输入样例2:
7+8.3
输入样例3:
3+4.5*(7+2)*(3)*((3+4)*(2+3.5)/(4+5))-34*(7-(2+3))
样例输出
输出样例1:
3.40
输出样例2:
15.30
输出样例3:

454.75

AC代码:
参考链接:https://blog.csdn.net/reidsc/article/details/54669433
#include<iostream>
#include<stdio.h>
#include<stack>
#include<cstring>
#include<algorithm>
using namespace std;
stack<char> s1;//数字
stack<char> s2;//运算符
stack<double> s3;
char ch[1010]={0};
int pro(char c)
{
    if(c=='('||c==')') return 1;
    if(c=='+'||c=='-')return 2;
    if(c=='*'||c=='/')return 3;

}
bool isy(char c)
{
    if(c=='('||c==')'||c=='+'||c=='-'||c=='*'||c=='/')
        return true;
    else
        return false;
}
double cal(double aa,double bb,char c)
{
    if(c=='+')
        return aa+bb;
    if(c=='-')
        return bb-aa;
    if(c=='*')
        return aa*bb;
    if(c=='/')
        return bb/aa;
}
int main()
{
    string str;
    cin>>str;
    //生成后缀表达式
    //考虑运算符的优先级,*/高于+-
    //根据运算规则,优先级高的直接放进去即可
    int n=str.length();
    for(int i=0; i<n; i++)
    {
        if((str[i]>='0'&&str[i]<='9')||str[i]=='.')
        {
            s1.push(str[i]);
            if(isy(str[i+1])||i==n-1)//判断情况请注意。如果是最后一个也需要进行判断
                s1.push('#');
        }
        else if(s2.empty()||str[i]=='('||pro(str[i])>pro(s2.top()))
            s2.push(str[i]);
        else if(str[i]==')')
        {
            while(s2.top()!='(')
            {
                s1.push(s2.top());
                s2.pop();
            }
            s2.pop();//弹出左括号。
        }
        else {
        //这里写的时候一开始出错了,需要循环判断符号的优先级
            while(!s2.empty()&&pro(s2.top())>=pro(str[i])&&str[i]!='(')
        {
            s1.push(s2.top());
            s2.pop();
        }
            s2.push(str[i]);//最后把自己放进去。
        }
    }
    while(!s2.empty())
    {//把剩下的运算符放进去
        s1.push(s2.top());
        s2.pop();
    }
    //此时后缀表达式在栈中。还需要取数,挪栈。
    int m=s1.size();
    int k=m;
    while(!s1.empty())
    {
        ch[m-1]=s1.top();
        s1.pop();
        m--;
    }
    //从左到右扫描ch
    for(int i=0; i<k; i++)
    {
        //如果是数字
        if(ch[i]=='#')continue;
        if(ch[i]>='0'&&ch[i]<='9')
        {
            double sum=0;
            double zs=0,xs=0;
            while(ch[i]!='.'&&ch[i]!='#')//这里进行整数部分的计算
            {
                zs=zs*10+(ch[i]-'0');
                i++;
            }
            if(ch[i]=='.')i++;
            int p=1;
            while(ch[i]!='#')//这里进行小数部分的计算
            {
                xs=xs+(ch[i]-'0')*pow(10,-p);
                p++;
                i++;
            }
            sum=zs+xs;
            s3.push(sum);
        }
        else if(isy(ch[i]))  //如果是运算符
        {
            double aa=s3.top();
            s3.pop();
            double bb=s3.top();
            s3.pop();
            aa=cal(aa,bb,ch[i]);
            s3.push(aa);
        }
    }
    printf("%.2f",s3.top());
    return 0;
}

PS:写了有5个小时。。。。辣鸡。深入理解了表达式求值。

1.生成后缀表达式。先生成后缀表达式存在一个栈里,需要对表达式中的每一位进行判断,如果是数字或小数点怎么办,如果是括号和运算符,重点是需要考虑符号优先级,什么时候入符号栈什么时候弹出符号栈。并将栈中的倒序放进数组。

2.计算后缀表达式。扫描后缀表达式,遇到数字放进栈里,遇到符号从栈顶弹出两个计算,后放进栈里。

看到一个AC的python3的代码只有28B,==,所以我要学python。==


猜你喜欢

转载自blog.csdn.net/huanting74/article/details/80372579