• Leetcode 224. 基本计算器


    实现一个基本的计算器来计算一个简单的字符串表达式的值。

    字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格  。

    示例 1:

    输入: "1 + 1"
    输出: 2
    示例 2:

    输入: " 2-1 + 2 "
    输出: 3
    示例 3:

    输入: "(1+(4+5+2)-3)+(6+8)"
    输出: 23
    说明:

    你可以假设所给定的表达式都是有效的。
    请不要使用内置的库函数 eval。

    链接:https://leetcode-cn.com/problems/basic-calculator
    思路:双栈

    解法一经过了一个中间过程,先转为了后缀表达式然后进行求值。我们其实可以直接利用两个栈,边遍历边进行的,这个方法是我当时上课学的方法。从 这里 把过程贴到下边,和解法一其实有些类似的。

    使用两个栈,stack0 用于存储操作数,stack1 用于存储操作符
    从左往右扫描,遇到操作数入栈 stack0
    遇到操作符时,如果当前优先级低于或等于栈顶操作符优先级,则从 stack0 弹出两个元素,从 stack1 弹出一个操作符,进行计算,将结果并压入stack0,继续与栈顶操作符的比较优先级。
    如果遇到操作符高于栈顶操作符优先级,则直接入栈 stack1
    遇到左括号,直接入栈 stack1。
    遇到右括号,则从 stack0 弹出两个元素,从 stack1 弹出一个操作符进行计算,并将结果加入到 stack0 中,重复这步直到遇到左括号

    以上来自 leetcode题解

    自己的想法:都在代码里面

    class Solution {
       public int calculate(String s) {
        
        //先将所有的
            char[] array=s.toCharArray();
    //        System.out.println(array);
    //        System.out.println(array[0]);
            //定义数字栈 符号栈
            Stack<Integer> num=new Stack<>();
            Stack<Character> op =new Stack<>();
            int n= array.length;
    //        System.out.println(n);
            int is_calculate=-1;//定义是否能计算
            int temp_num=-1;
    //        System.out.println(isOperation("+"));
            // char c='+';
            // String ak=c+"";
            // System.out.println(ak);
    
            for(int i=0;i<n;i++)//循环遍历
            {
                if(array[i]==' ')//如果是空格 则进行
                {
                    continue;
                }
    
    
                if(isNumber(array[i]))//如果是数字的话
                {
                    if(temp_num==-1)
                    {//如果前面没有遇到过数字
                        temp_num=array[i]-'0';
                    }else
                    {
                    //如果前面遇到了数字了 那就是要将前面的*10在加上现在的temp
                        temp_num=temp_num*10+(array[i]-'0');
                    }
                }else//遇到的不是数字 是操作符或者括号 先将之前的数字进堆栈(所以是遇到了符号才会压入堆栈)
                {
                    if(temp_num!=-1)
                    {
                        num.push(temp_num);//压到堆栈中
                        temp_num=-1;//然后等下一个数字
                    }
                    //判断了不是空格 不是数字之后 是判断操作符号
                    if(isOperation(array[i]))
                    {
                        //如果是操作符号的话
                        while (!op.isEmpty())
                        {
                            //只要操作符zhan不为空 或者遇到了左括号 就一直运算到最后
                            if(op.peek()=='(')
                            {
                                break;
                            }
    
                            int num1=num.pop();
                            int num2=num.pop();
    
                            if (op.pop()=='+')
                            {
                                num.push(num1+num2);
                            }else//如果是减号
                            {
                                num.push(num2-num1);
                            }
                        }
                        //前面的运算符计算完之后 将这个运算符入栈
                        op.push(array[i]);
                    }
                    else//遇到的不是数字 也不是操作符号 那只有左右括号了
                    {
                        if(array[i]=='(')
                        {//如果是左括号 直接入栈
                            op.push(array[i]);
                        }
    
                        if (array[i]==')')
                        {
                            //如果遇到了右边的括号 那直接进行一个运算 直到遇见(,其实这边也就一个运算符 因为之前的都被算过了
                            while (op.peek()!='(')
                            {
                                int num1=num.pop();
                                int num2=num.pop();
    
                                if (op.pop()=='+')
                                {
                                    num.push(num1+num2);
                                }else//如果是减号
                                {
                                    num.push(num2-num1);
                                }
                            }
                            //括号内计算完之后 将左括号出站 右括号从来没进过站 所以不用出站
                            op.pop();
                        }
                    }
                }
    
            }
            //(由于是遇到了符号才会压入堆栈)考虑到有些只有一个运算符号的情况 比如 1+1 这时候没有遇到下一个运算符 那之前的就没有办法运算了
            if(temp_num!=-1)
            {
                num.push(temp_num);
            }
    //        System.out.println(num.size());
            while (!op.isEmpty()) {
                int num1 = num.pop();
                int num2 = num.pop();
                if (op.pop() == '+') {
                    num.push(num1 + num2);
                } else {
                    num.push(num2 - num1);
                }
            }
        return num.pop();
    }
    
    private boolean isNumber(char c) {
        return c >= '0' && c <= '9';
    }
    
     private static boolean isOperation(char t) {
            return t=='+' || t=='-' || t=='*' || t=='/';
        }
    }
  • 相关阅读:
    2014最后一篇英语笔记(新开始)
    记录:CSS特殊性——权值规则
    grunt--自动化打包工具使用
    【移动端】---点透事件
    [前端性能提升]--图片转化为base64
    js--cookie
    1.倒数几秒弹窗关闭
    ES6就是ES2015 的主要内容
    call 与 apply的区别
    34枚金币时间管理法
  • 原文地址:https://www.cnblogs.com/William-xh/p/13799043.html
Copyright © 2020-2023  润新知