实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。
示例 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=='/'; } }