2017西工大机试 计算表达式

题目描述:输入行数,再在每行输入一个表达式,得出结果

输入示例:
3
1+1
2.2/3
1+2*3
输出示例:
2.0
0.7
7.0

思路:把中缀表达式转后缀表达式,边转换边计算。具体:设置一个数字栈s1,一个符号栈s2,遍历字符串s,数字直接进栈,在计算数学算式时是先乘除后加减,同优先级从左到右按顺序计算。所以遇到'+'、'-',s2里的符号都要在'+'、'-'之前算,把s2里符号依次出栈,不断取s1的两个数字计算结果并入栈s1,再把符号入栈。遇到'*'、'\',把s2里的'*'、'\'出栈,计算结果,入栈符号。最后处理符号栈剩余符号。

#include <iostream>
#include <string>
#include <stack>
using namespace std;

double get_number(string &s,int &i)
{
    string number;
    for(;i<s.length();i++) {
        if((s[i]>='0'&&s[i]<='9')||s[i]=='.'){
                number.insert(number.end(),s[i]);
        }
        else {
            i--;
            break;
        }
    }
    return stod(number);
}

void symbol(stack<double> &s1,stack<char> &s2)
{
    double x,y,res;
    char ch=s2.top();
    s2.pop();
    y=s1.top();
    s1.pop();
    x=s1.top();
    s1.pop();
    switch(ch){
        case '+':   res=x+y;
                    break;
        case '-':   res=x-y;
                    break;
        case '*':   res=x*y;
                    break;
        case '/':   res=x/y;
                    break;
    }
    s1.push(res);
}

double calculate(string &s)
{
    stack<double> s1;
    stack<char> s2;
    for(int i=0;i<s.length();i++) {
        if(s[i]=='+'||s[i]=='-') {
            while(!s2.empty())
                symbol(s1,s2);
            s2.push(s[i]);
        }
        else if(s[i]=='*'||s[i]=='/') {
                while(!s2.empty()&&s2.top()!='+'&&s2.top()!='-')
                    symbol(s1,s2);
                s2.push(s[i]);
        }
        else
            s1.push(get_number(s,i));
    }

    while(!s2.empty())
        symbol(s1,s2);
    return s1.top();

}

int main()
{
    int n;
    cin>>n;
    while(n--) {
        string s;
        cin>>s;
        printf("%.1f\n",calculate(s));
    }
}

posted @ 2020-03-11 12:47  iClaire  阅读(259)  评论(0编辑  收藏  举报