【leetcode】基本計算器II C++/Go(棧)

問題描述

給你一個字符串表達(dá)式 s ,請你實現(xiàn)一個基本計算器來計算并返回它的值。

整數(shù)除法僅保留整數(shù)部分。

示例 1:

輸入:s = "3+2*2"
輸出:7

示例 2:

輸入:s = " 3/2 "
輸出:1

提示:

  • 1 <= s.length <= 3 * 105
  • s 由整數(shù)和算符 ('+', '-', '*', '/') 組成,中間由一些空格隔開
  • s 表示一個 有效表達(dá)式
  • 表達(dá)式中的所有整數(shù)都是非負(fù)整數(shù),且在范圍 [0, 231 - 1] 內(nèi)
  • 題目數(shù)據(jù)保證答案是一個 32-bit 整數(shù)

棧思想

想象一下,一個計算器怎么實現(xiàn),一般來說都是使用棧這個數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)的。那么如何確定不同符號的優(yōu)先級呢?

首先,'*''/'的優(yōu)先級要高于'+''-'。那么我們制定一個策略:

  • 當(dāng)遇到'*''/'的時候,我們不將當(dāng)前這個數(shù)字進(jìn)行入棧操作,而是將這個數(shù)字與棧頂元素進(jìn)行 符號運算,將運算結(jié)果更新為當(dāng)前棧頂元素。
  • 當(dāng)遇到'+''-'時,我們直接將當(dāng)前元素入棧,只不過特別的,對于'-',我們?nèi)霔5氖钱?dāng)前數(shù)字的相反數(shù)。

例如,對于下面的表達(dá)式
3 + 2 * 2

初始化符號presign = '+',我們遍歷到一個非數(shù)字符號的時候,我們將前面的數(shù)字入棧,前面的數(shù)字也就是數(shù)字3,然后我們可以將3直接入棧

第一步

往后繼續(xù),遇到符號 '*',我們將前面的數(shù)字2入棧,更新當(dāng)前的presign為'*'

第二步

到字符串最后一位也是一個結(jié)束的標(biāo)志,我們需要將前面的數(shù)字進(jìn)行入棧,但是當(dāng)前的presign為'*',我們將當(dāng)前數(shù)字2與棧頂數(shù)字2進(jìn)行相乘為4,然后更新為棧頂元素。

第三步

最后,將棧內(nèi)所有的元素相加就能夠得到最終的計算結(jié)果:
3 + 4 = 7

C++實現(xiàn)(vector模擬棧)

class Solution {
public:
    int calculate(string s) {
        int n = s.length();
        vector<int> nums;   // 聲明一個向量容器模擬棧
        // 初始化前一個數(shù)的符號為+號
        char presign = '+';
        int num = 0;
        for(int i = 0;i < n;++i){
            if(isdigit(s[i])) {
                // 假如是數(shù)字
                num = num * 10 + (s[i] - '0');
            }
            if(!isdigit(s[i]) && s[i] != ' ' || i == n-1) {
                // 不是數(shù)字也不是符號,即是一個運算符或者到達(dá)了字符串的結(jié)尾
                switch(presign){
                    case '+':{
                        nums.push_back(num);break;
                    }
                    case '-':{
                        nums.push_back(-num);break;
                    }
                    case '*':{
                        nums.back() = nums.back() * num;break;
                    }
                    case '/':{
                        nums.back() = nums.back() / num;break;
                    }
                    default:break;
                }
                presign = s[i];
                num = 0;
            }
        }
        int ret = 0; // 求和得出結(jié)果
        for(auto each:nums) ret += each;
        return ret;
    }
};

Go實現(xiàn)(slice模擬棧)

func calculate(s string) int {
    n := len(s)
    nums := []int{}
    // 初始化
    num := 0
    var presign byte = '+'
    
    for i := 0; i < n; i++ {
        // 判斷當(dāng)前字符是否為數(shù)字
        isdigit := (s[i] >= '0' && s[i] <= '9')
        if isdigit {
            num = num * 10 + int(s[i] - '0')
        }
        if !isdigit && s[i] != ' ' || i == n - 1 {
            switch presign {// 各種不同符號的處理方法
                case '+':
                    nums = append(nums,num)
                case '-':
                    nums = append(nums,-num)
                case '*':
                    nums[len(nums)-1] *= num
                case '/':
                    nums[len(nums)-1] /= num
            }
            // 更新符號與數(shù)值
            presign = s[i]
            num = 0
        }
        
    }
    ret := 0
    for _, val := range nums {
        ret += val
    }
    return ret
}

注意:

這個計算器還是比較簡單的,只包括('+', '-', '*', '/')這四種運算符,還不包括括號運算符,并且數(shù)字都是非負(fù)整數(shù)。


參考:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容