zoukankan      html  css  js  c++  java
  • [LeetCode]104. Basic Calculator II基本计算器

    Implement a basic calculator to evaluate a simple expression string.

    The expression string contains only non-negative integers, +-*/ operators and empty spaces . The integer division should truncate toward zero.

    You may assume that the given expression is always valid.

    Some examples:

    "3+2*2" = 7
    " 3/2 " = 1
    " 3+5 / 2 " = 5
    

    Note: Do not use the eval built-in library function.

    本题与基本计算器I不同的一点是表达式不包含括号,取而代之的是包含有乘除运算。

    解法1:先遍历一遍表达式去除无效的空格。然后从头至尾遍历表达式,遇到数字和加减号分别进操作数或操作符栈,遇到乘除号则在操作数栈中取出左操作数,同时从表达式中读出右操作数,计算好结果后入操作数栈。一遍完成后将乘除运算计算完成。根据加减运算的从左至右规律,先将操作数和操作符栈中的元素全部搬运到新的操作数和操作符栈,然后不断从新的操作符栈取操作符,从新的操作数栈取两个操作数,进行加减运算,直至没有操作符,操作数栈顶即为结果。

    class Solution {
    public:
        int calculate(string s) {
            stack<char> opc;
            stack<int> opn;
            int k = 0;
            for (int i = 0; i < s.size(); ++i) {
                if (!isspace(s[i])) s[k++] = s[i];
            }
            s.resize(k);
            for (int i = 0; i < k; ++i) {
                if (isdigit(s[i])) {
                    int d = s[i] - '0';
                    while (i < k && isdigit(s[++i]))
                        d = d * 10 + s[i] - '0';
                    --i;
                    opn.push(d);
                }
                else if (s[i] == '+' || s[i] == '-')
                    opc.push(s[i]);
                else if (s[i] == '*' || s[i] == '/') {
                    char dom = s[i];
                    int num1 = opn.top();
                    opn.pop();
                    int num2 = (int)(s[++i] - '0');
                    while (i < k && isdigit(s[++i]))
                        num2 = num2 * 10 + s[i] - '0';
                    --i;
                    if (dom == '*') opn.push(num1 * num2);
                    else opn.push(num1 / num2);
                }
            }
            stack<char> c;
            stack<int> n;
            while (!opc.empty()) {
                c.push(opc.top());
                opc.pop();
            }
            while (!opn.empty()) {
                n.push(opn.top());
                opn.pop();
            }
            while (!c.empty()) {
                int num1 = n.top();
                n.pop();
                int num2 = n.top();
                n.pop();
                char aoa = c.top();
                c.pop();
                if (aoa == '+') n.push(num1 + num2);
                else n.push(num1 - num2);
            }
            return n.top();
        }
    };

    解法2:解法1的一个繁琐之处在于为了从左至右计算加减运算需将两个栈倒过来,可以想办法将这个过程省去。每次遇到第二个操作符,只要不是乘除号,则可以将前面一部分表达式按从左至右顺序计算好。

    class Solution {
    public:
        int calculate(string s) {
            stack<char> opc;
            stack<int> opn;
            int k = 0;
            for (int i = 0; i < s.size(); ++i) {
                if (!isspace(s[i])) s[k++] = s[i];
            }
            s.resize(k);
            for (int i = 0; i < k; ++i) {
                if (isdigit(s[i])) {
                    int d = s[i] - '0';
                    while (isdigit(s[++i]))
                        d = d * 10 + s[i] - '0';
                    --i;
                    opn.push(d);
                }
                else if (s[i] == '+' || s[i] == '-') {
                    if (!opc.empty()) {
                        char dom = opc.top();
                        opc.pop();
                        int num2 = opn.top();
                        opn.pop();
                        int num1 = opn.top();
                        opn.pop();
                        if (dom == '+') opn.push(num1 + num2);
                        else opn.push(num1 - num2);
                    }
                    opc.push(s[i]);
                }
                else if (s[i] == '*' || s[i] == '/') {
                    char dom = s[i];
                    int num1 = opn.top();
                    opn.pop();
                    int num2 = (int)(s[++i] - '0');
                    while (isdigit(s[++i]))
                        num2 = num2 * 10 + s[i] - '0';
                    --i;
                    if (dom == '*') opn.push(num1 * num2);
                    else opn.push(num1 / num2);
                }
            }
            if (!opc.empty()) {
                char dom = opc.top();
                opc.pop();
                int num2 = opn.top();
                opn.pop();
                int num1 = opn.top();
                opn.pop();
                if (dom == '+') opn.push(num1 + num2);
                else opn.push(num1 - num2);
            }
            return opn.top();
        }
    };

    解法3:将中缀表达式转换为前缀或者后缀表达式再进行计算。见基本计算器I

  • 相关阅读:
    【转】HEIF图片存储格式探秘
    【转】Maven项目中将配置文件打包到jar包中
    C++ 单词接龙
    vector vector int 初始化
    哈夫曼树的特点
    哈夫曼树的构造
    单链表的逆转(测试数据)
    单链表的逆转
    二叉搜索树的插入
    二叉搜索数的应用
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/5032924.html
Copyright © 2011-2022 走看看