1. 程式人生 > 實用技巧 >Leetcode 224. 基本計算器

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=='/'; } }