#40779: 解答 python


n0970616056@gmail.com (CIOU-HE-CHEN)

學校 : 不指定學校
編號 : 273811
來源 : [111.253.1.171]
最後登入時間 :
2024-06-14 11:55:43
a017. 五則運算 | From: [27.247.62.93] | 發表日期 : 2024-06-12 21:33

解答:

import sys

def count(a, b, op): #a: int, b: int, c: str
    
    if (op=='+'):
        return a+b
    
    if (op=='-'):
        return a-b  
    if (op=='*'):
        return a*b
        
    if (op=='/'):
        return a//b #題目有說除法不要留小數
        
    if (op=='%'):
        return a%b
    
    return -999

def calculate(expr): #expr: str
    
    exprs = expr.split() #把每個數字, 號分開來
    opers = [] #裝str
    nums = [] #裝int
    
    prior = {'+':1, '-':1, '*':2, '/':2, '%':2, '(':-1}
    
    for ele in exprs:
        
        if ele=='(':
            opers.append('(')
            
        elif ele==')':
            
            #算到左括號為止,照理講括號裡面會只剩下+-,頂多最後面(opers最前面)有一個*/%
            while opers[-1] != '(': 
                
                #注意順序, nums的最前面會是比較晚加入的數字,也就是是計算時的第二個數字
                val2 = nums.pop(); val1 = nums.pop(); 
                op = opers.pop()
                
                result = count(val1, val2, op)
                nums.append(result)
            
            opers.pop() #pop掉'('
                
        elif ( ele in ['+', '-', '*', '/', '%'] ):
            
            while (opers and prior[ele]<=prior[opers[-1]]):
                
                #注意順序
                val2 = nums.pop(); val1 = nums.pop(); 
                op = opers.pop()
                
                result = count(val1, val2, op)
                nums.append(result)
            
            opers.append(ele)
            
        else: #ele是數字
            nums.append( int(ele) )
            
        
    while (opers): #把剩下的清掉,一樣,照理來講opers裡面會只剩下+-,頂多最前面有一個*/%
       
        val2 = nums.pop(); val1 = nums.pop(); #注意順序
        op = opers.pop()
                
        result = count(val1, val2, op)
        nums.append(result)
    
    #這個時候,opers應該要是空的, nums剩下一個數字,就是答案
    return nums[-1]

for inp in sys.stdin:
    
    ans = calculate(inp)
    print(ans)

 

好的,讓我用繁體中文來解釋這段程式碼的工作原理。 ### 函數 `count` ```python def count(a, b, op): # a: int, b: int, c: str if (op == '+'): return a + b if (op == '-'): return a - b if (op == '*'): return a * b if (op == '/'): return a // b # 題目有說除法不要留小數 if (op == '%'): return a % b return -999 ``` `count` 函數負責執行基本的數學運算。根據傳入的運算符 `op`,它分別執行加、減、乘、整除和取模運算,並返回結果。 ### 函數 `calculate` ```python def calculate(expr): # expr: str exprs = expr.split() # 把每個數字和符號分開來 opers = [] # 裝運算符的堆疊 nums = [] # 裝操作數的堆疊 prior = {'+': 1, '-': 1, '*': 2, '/': 2, '%': 2, '(': -1} for ele in exprs: if ele == '(': opers.append(ele) elif ele == ')': # 算到左括號為止,照理講括號裡面會只剩下 + -,頂多最後面 (opers 最前面) 有一個 * / % while opers[-1] != '(': # 注意順序,nums 的最前面會是比較晚加入的數字,也就是計算時的第二個數字 val2 = nums.pop() val1 = nums.pop() op = opers.pop() result = count(val1, val2, op) nums.append(result) opers.pop() # pop 掉 '(' elif ele in ['+', '-', '*', '/', '%']: while opers and prior[ele] <= prior[opers[-1]]: # 注意順序 val2 = nums.pop() val1 = nums.pop() op = opers.pop() result = count(val1, val2, op) nums.append(result) opers.append(ele) else: # ele 是數字 nums.append(int(ele)) while opers: # 把剩下的清掉,一樣,照理來講 opers 裡面會只剩下 + -,頂多最前面有一個 * / % val2 = nums.pop() val1 = nums.pop() op = opers.pop() result = count(val1, val2, op) nums.append(result) # 這個時候,opers 應該要是空的, nums 剩下一個數字,就是答案 return nums[-1] ``` `calculate` 函數負責解析並計算輸入的表達式。它使用兩個堆疊:`opers` 用來存儲運算符,`nums` 用來存儲操作數。函數的工作流程如下: 1. **初始化**:將表達式用空格分隔成多個部分存儲在 `exprs` 中,初始化運算符堆疊 `opers` 和操作數堆疊 `nums`,並定義運算符的優先級 `prior`。 2. **遍歷表達式**: - 如果遇到左括號 `'('`,將其壓入 `opers`。 - 如果遇到右括號 `')'`,彈出 `opers` 中的運算符並計算,直到遇到左括號 `'('`。 - 如果遇到運算符,根據優先級彈出 `opers` 中的運算符並計算,直到遇到優先級更低的運算符或堆疊為空,然後將當前運算符壓入 `opers`。 - 如果遇到數字,將其轉換為整數並壓入 `nums`。 3. **清理堆疊**:遍歷完表達式後,彈出並計算 `opers` 中剩餘的運算符,直到堆疊為空。 4. **返回結果**:此時 `nums` 中應只剩下一個數字,即表達式的結果。 ### 主程序 ```python for inp in sys.stdin: ans = calculate(inp) print(ans) ``` 主程序從標準輸入讀取每一行輸入,並調用 `calculate` 函數計算結果,然後打印結果。 ### 總結 這段程式碼實現了一個簡單的表達式計算器,可以處理帶有括號和基本運算符(加、減、乘、除、取模)的表達式。通過使用兩個堆疊來管理運算符和操作數,確保了運算的正確順序和優先級。

 
ZeroJudge Forum