zoukankan      html  css  js  c++  java
  • Basic Calculator

    本博客介绍leetcode上的一道不难,但是比较经典的算法题。

    题目如下:

    Implement a basic calculator to evaluate a simple expression string.

    The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .

    You may assume that the given expression is always valid.

    Some examples:

    也可以直接参考 https://leetcode.com/problems/basic-calculator/

    这是简单的加减计算运算题,一个直观的思路是运用栈,以及用后缀表达式求值。实现这一种算法,需要构造两个栈,分别是运算符栈和数字栈,然后将输入的中序表达式在转化为后续表达式的过程中求值。

    考虑到这道题目的特殊性,运算符只有加减和括号,我们可以转化加减运算符为(±1),这样可以省略计算时的判断语句,而直接将转化后的运算符数作为被加(减)数的系数

    这是我的代码

    int calculate(string s) {
        s.push_back('#');       //防止栈溢出
        stack<int>num;          //数字栈
        stack<int>oper;         //运算符栈
        for(int i=0; i<s.length()-1;++i)
        {
            if(isdigit(s[i]))   //判断数字,压入数字栈
            {
                int temp = s[i]-'0';
                while(++i && isdigit(s[i]))
                {
                    temp = temp * 10 + s[i] - '0'; 
                }
                num.push(temp);
            }
            switch (s[i]){       
            case '(':           //'('直接压入栈,其代表数为0
                oper.push(0);
                break;
            case '+':
            case '-':
                if(!oper.empty() && oper.top() != 0)      //栈中有加减运算符,则先弹出,再压入现在的运算符
                {
                    int num1 = num.top(); num.pop();
                    int num2 = num.top(); num.pop();
                    num.push(num2 + num1 * oper.top());
                    oper.pop();
                }
                if(s[i] == '-')
                    oper.push(-1);
                else oper.push(1);
                break;
            case ')':                       //为')',则一直弹出栈至弹出第一个'('
                if(oper.top() == 0)
                    oper.pop();
                else
                {
                    int num1 = num.top(); num.pop();
                    int num2 = num.top(); num.pop();
                    num.push(num2 + num1 * oper.top());
                    oper.pop();
                    oper.pop();
                }
                break;
            case '#':
                break;
            }
        }
        if(oper.empty())
                return num.top();
            else
            {
                int num1 = num.top(); num.pop();
                int num2 = num.top(); num.pop();
                return (num2 + num1 * oper.top());
            }
    }

    其实这个算法的效率并不是很高,原因在于,每个数字都要压栈、退栈,每个操作符(除了')')也同样如此。

    下面这个算法是讨论区上面的比较优秀的算法,其亮点是

    1. 用独立的变量存储上次的数字和加减运算符,在n次连续加减运算时省略了分别n-1次出入栈;
    2. 遇到'(',只压入前面的加减运算符,默认为加法。
    class Solution {
    public:
        int calculate(string s) {
            stack <int> nums, ops;
            int num = 0;
            int rst = 0;
            int sign = 1;
            for (char c : s) { 
                if (isdigit(c)) {
                    num = num * 10 + c - '0';
                }
                else {
                    rst += sign * num;
                    num = 0;
                    if (c == '+') sign = 1;
                    if (c == '-') sign = -1;
                    if (c == '(') {
                        nums.push(rst);
                        ops.push(sign);
                        rst = 0;
                        sign = 1;
                    }
                    if (c == ')' && ops.size()) {
                        rst = ops.top() * rst + nums.top();
                        ops.pop(); nums.pop();
                    }
                }
            }
            rst += sign * num;
            return rst;
        }
    };

    也可以参考https://leetcode.com/discuss/53921/16-ms-solution-in-c-with-stacks

  • 相关阅读:
    rem适配布局(rem+less+媒体查询 和 rem+flexible.js)
    flex布局(弹性布局)
    移动端技术选型
    移动端(视口(meta),像素比,二倍图(图片,背景图,精灵图),css初始化(normalize.css),特殊样式,常见屏幕尺寸)
    案例-3D旋转木马
    CSS新特性(3D转换,perspective(透视),transfrom-style(子元素是否开启三维环境))
    css3 新特性(动画)
    案例-2D会旋转的盒子(rotate), 会缩放的盒子(scale),动画(animation)
    listener启动与关闭
    Oracle在Linux内核参数的修改
  • 原文地址:https://www.cnblogs.com/zhx14/p/4916089.html
Copyright © 2011-2022 走看看