【Leetcode】227. Basic Calculator II

来源:互联网 发布:手机图片搜索软件 编辑:程序博客网 时间:2024/06/07 12:27

227. 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.

题目分析:

输入一个运算的字符串,需要输出字符串的运行结果。题目假定输入的运算字符串都是有意义的。

思路简介:

思路一:只从字符串处理的角度出发的话,我考虑使用Stack来处理这题。

首先,将字符串从后向前存入栈中,这样栈弹出的时候就与字符串的真实顺序一致。每次存要么存数,要么存操作符,这样之后弹出的元素就是一个完整的部分。

初始化sum=0;每次Stack弹出三个元素,其中一定包含两个数字和一个操作符号(num1,oper,num2)。

如果符号是"+"那么将第一个数字加到sum中,将num2压回栈中(因为不知道num2之后的操作符是否比oper优先级高)

如果符号是"-"那么将num2取负,并压回栈中。

如果符号是" * “ ” / ",将num1和num2的运算结果压回栈中。

之后代码我实现了两个方式,一个是将操作符和数字都存在一个Stack<String>中。二是分开存储NumStack<Integer>/OperStack<Character>,但是二者的速度差不多,失败~~

复杂度:

时间复杂度O(N)

空间复杂度O(N)

代码:

public class Solution {
    public int calculate(String s) {
//方法一,用一个栈来做这件事        

/*
        Stack<String> aStack = new Stack<String>();
        getStack(aStack,s);
        int sum=0;
        while(true){
            String num1=aStack.pop();
            if(aStack.isEmpty()==true){
                sum += Integer.parseInt(num1);
                break;
            }
            String oper=aStack.pop();
            String num2=aStack.pop();
            if(oper.charAt(0)=='+'||oper.charAt(0)=='-'){
                sum +=Integer.parseInt(num1);
                if(oper.charAt(0)=='-'){
                    num2 = "-"+num2;
                }
                aStack.push(num2);
            }else{
                if(oper.charAt(0)=='*'){
                    aStack.push(Integer.parseInt(num1)*Integer.parseInt(num2)+"");
                }else{
                    aStack.push(Integer.parseInt(num1)/Integer.parseInt(num2)+"");
                }   
            }
            
        }
        return sum;
        */

//方法二:分开处理这件事
        Stack<Integer> aNumStack= new Stack<Integer>();
        Stack<Character> aOperStack= new Stack<Character>();
        int sum = 0;
        getStack(aOperStack,aNumStack,s);
        if(aOperStack.isEmpty()==true){
            return aNumStack.pop();
            //break;
        }
        while(true){
            int num1 = aNumStack.pop();
            
            int num2 = aNumStack.pop();
            char oper = aOperStack.pop();
            
            if(oper=='+'||oper=='-'){
                sum += num1;
                if(oper == '-'){
                    num2 = -1*num2;
                }
                aNumStack.push(num2);
            }else{
                if(oper == '*'){
                    aNumStack.push(num1*num2);
                }else{
                    aNumStack.push(num1/num2);
                }
            }
            if(aOperStack.isEmpty()==true){
                sum+= aNumStack.pop();
                break;
            }
        }
        return sum;
    }
    //用一个栈来解决所有问题,简单但是速度慢
    public void getStack(Stack<String> aStack,String s){
        String aSec="";
        for(int i=s.length()-1;i>=0;i--){
            //String aSec="";
            if(s.charAt(i)!=' '){
                if(s.charAt(i)<='9'&&s.charAt(i)>='0'){
                    aSec = s.charAt(i)+aSec;
                }else{
                    aStack.push(aSec);
                    aStack.push(s.charAt(i)+"");
                    aSec="";
                }
            }
        }
        aStack.push(aSec);
    }
    //一个栈存储数字,一个栈存储操作符
    public void getStack(Stack<Character> aOperStack,Stack<Integer> aNumStack,String s){
        String aSec="";
        for(int i=s.length()-1;i>=0;i--){
            if(s.charAt(i)!=' '){
                if(s.charAt(i)<='9' && s.charAt(i)>= '0'){
                    aSec = s.charAt(i)+aSec;
                }else{
                    aNumStack.push(Integer.parseInt(aSec));
                    aOperStack.push(s.charAt(i));
                    aSec="";
                }
            }
        }
        aNumStack.push(Integer.parseInt(aSec));
    }
    
}

运行结果:

(依旧不能贴图,我上个数字)8.78%

ps:这个方法是比较暴力的方法,之后好的方法再陆续补充


———————————————————————————————————————————————————————————

【转载自】微信公众号:每日一道算法题

求一个简单的数学运算表达式的值,运算符总是在两个运算对象之间。一般用数学表达式的是 中缀表达式 如1+5*2。中缀表达式的特点:1.对人比较友好,但是对机器并不友好,不利于计算(编译器一般会将中缀表达式翻译成逆波兰表达式 )2,不能表示计算的顺序,需要借助括号等符号;3。操作符在操作数的中间。

逆波兰表达式又叫后缀表达式,据说是波兰人发明的。后缀表达式的特点是操作符都在操作数的后面,并且特别方便计算。因为它的顺序可以表示计算的顺序,不需要借助括号。

改进1:

不需要将String 存储到 Stack中,直接从前向后遍历String,可以将空间复杂度缩小为 O(1)


0 0
原创粉丝点击