题解 | #四则运算#

四则运算

https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e

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

class Compute {
  private:
    //算式
    string expression;

    //用于存储数值
    stack<float> si;

    //用于存储运算符
    stack <char> sc;

  public:
    //构造函数
    Compute(const string s);

    //析构函数
    ~Compute();

    //计算
    float calculate(void);

    //判断ch是否是有效字符
    bool isValid(const char ch)const;

    //存入f
    void credited(const float f);

    //处理括号(间接递归)
    istringstream& handleParenthes(istringstream& iss,
                                   const char leftParenthes = '(');
};

Compute::Compute(const string s) {
    this->expression = s;

    //清空栈
    while (!this->si.empty())
        this->si.pop();
    while (!this->sc.empty())
        this->sc.pop();
    return;
}

Compute::~Compute() {
}

float Compute::calculate(void) {
    //输入重定向到字符串
    const string s = this->expression;
    istringstream iss(s);
    float f = 0;
    char ch = 0;
    while (this->isValid(ch = iss.peek())) {

        //如果遇到括号,截取字符串到对应的右括号,递归运算并将结果存入栈
        if ((ch == '{') || (ch == '[') || (ch == '(')) {
            this->handleParenthes(iss, ch);
            continue;
        }
        //如果遇到数字,存入栈中
        if (('0' <= ch) && (ch <= '9')) {
            iss >> f;
            this->credited(f);
            continue;
        }

        //如果是加或减,记为正数或负数,存入栈中,延后计算
        if ((ch == '+') || (ch == '-')) {
            iss >> ch;
            if (ch == '-')
                this->sc.push(ch);
            continue;
        }

        //如果是乘或除直接与下一个数字进行运算
        if ((ch == '*') || (ch == '/')) {
            iss >> ch;
            this->sc.push(ch);
            continue;
        }
    }

    //累加
    float result = 0;
    for (float add = 0; !this->si.empty(); result += add) {
        add = this->si.top();
        this->si.pop();
    }
    return result;
}

bool Compute::isValid(const char ch) const {
    if (('0' <= ch) && (ch <= '9'))
        return true;
    switch (ch) {
        case '+':
        case '-':
        case '*':
        case '/':
        case '(':
        case ')':
        case '[':
        case ']':
        case '{':
        case '}':
            return true;
        default:
            return false;
    }
}

void Compute::credited(const float f) {
    //如果符号栈中没有运算符,直接存储
    if (this->sc.empty()) {
        this->si.push(f);
        return;
    }

    //如果存储了减号,存入f的相反数
    if (this->sc.top() == '-') {
        this->si.push(-f);
        this->sc.pop();
        return;
    }

    //如果存储了乘或除,直接与栈顶数据进行运算
    if (this->sc.top() == '*') {
        this->si.top() *= f;
        this->sc.pop();
        return;
    }
    if (this->sc.top() == '/') {
        this->si.top() /= f;
        this->sc.pop();
        return;
    }
    this->si.push(f);
    return;
}

istringstream& Compute::handleParenthes(istringstream& iss,
                                        const char leftParenthes) {
    char rightParenthes, ch;

    //为左括号匹配右括号
    switch (leftParenthes) {
        case '(':
            rightParenthes = ')';
            break;
        case '[':
            rightParenthes = ']';
            break;
        case '}':
            rightParenthes = '}';
            break;
        default:
            break;
    }
    float f = 0;
    iss >> ch;
    string s1;

    //记录层数,确保遇到嵌套括号时找准匹配的右括号
    int layer = 0;
    while (iss >> ch) {
        if (ch == leftParenthes)
            layer++;
        if (ch == rightParenthes) {
            if (layer == 0)
                break;
            layer--;
        }
        s1.append(1, ch);
    }

    //间接递归进行运算
    f = Compute(s1).calculate();
    this->credited(f);
    // TODO: 在此处插入 return 语句
    return iss;
}

int main() {
    string s;
    while (cin >> s) { // 注意 while 处理多个 case
        cout << Compute(s).calculate() << endl;
    }
}
// 64 位输出请用 printf("%lld")

全部评论

相关推荐

04-27 08:59
常州大学 Java
牛客139242382号:《两门以上汇编语言》
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务