(CSP)201912-3化學方程式-python實現


  • 測試數據
11
H2+O2=H2O
2H2+O2=2H2O
H2+Cl2=2NaCl
H2+Cl2=2HCl
CH4+2O2=CO2+2H2O
CaCl2+2AgNO3=Ca(NO3)2+2AgCl
3Ba(OH)2+2H3PO4=6H2O+Ba3(PO4)2
3Ba(OH)2+2H3PO4=Ba3(PO4)2+6H2O
4Zn+10HNO3=4Zn(NO3)2+NH4NO3+3H2O
4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH
Cu+As=Cs+Au
  • 代碼
n = int(input())

def findDigit(i): # 提取數字,並返回提取完的位置下標
    num=''
    while i < len(el) and el[i].isdigit():
        num += el[i]
        i+=1
    num = int(num) if num else 1 # 若沒有則默認1
    return num, i

def findLetter(i): # 提取一個元素符號,Ag,O,並返回提取完的位置下標
    if el[i].isupper():
        let = el[i]
    else:
        return '', i
    i += 1
    while i < len(el) and el[i].islower():
        let += el[i]
        i+=1
    return let, i
        
def judge(i):   # 獲取當前i下標塊的結果, 由 tmp 儲存返回
    tmp = {}
    if el[i] == '(':    # 處理 括號+后綴(NO3)2 部分, 由於存在嵌套,使用遞歸, 並存入tmp
        i+=1
        while el[i]!=')':       # 循環查找,直到達到臨界條件。臨界條件:碰到 右括號 即退出。 
            i, tmp_c = judge(i)
            for k in tmp_c:
                tmp[k] = tmp.get(k, 0) + tmp_c[k]            
        i += 1
        num, i = findDigit(i)   # 退出遞歸后,獲取括號后綴,並乘以tmp中的結果
        for k in tmp:
            tmp[k] *= int(num)
    else:               # 處理 元素+后綴O2 部分, 較簡單, 分別提取元素與數字, 並存入tmp
        s, i = findLetter(i)
        num, i = findDigit(i)
        tmp[s] = tmp.get(s,0) + int(num)
    return i, tmp


def analyze(el): # 分析結果由ans_t返回
    el = list(el)
    ans_t = {}
    
    i = 0 # 記錄下標位置
    el_num, i = findDigit(i) # 獲取前綴系數,乘以ans_t結果
    
    while True: # 循環分塊查找,每一個 括號+后綴(NO3)2 或 元素+后綴O2 為一部分
        
        i, tm = judge(i) # tm為查找結果
        for k in tm:     # 將tm匯總到ans_t中
            ans_t[k] = ans_t.get(k,0)+tm[k]
        #print(tm)    
        if i >= len(el): # 下標越界,則查找結束
            break
    
    if el_num != 1:     # 結果乘以前綴系數
        for k in ans_t:
            ans_t[k] *= el_num
    return ans_t        # 返回表達式查詢結果


for _ in range(n):
    left, right = input().split('=') # 分為左右兩部分
    
    left = left.split('+')          # 提取各個表達式
    right = right.split('+')
    left_ans = {}                   # 保存最終統計結果
    right_ans = {}
    #print(left,right)
    
    for el in left:                 # 分析每個表達式的成分
        ans_t = analyze(el)
        for k in ans_t:     # 匯總到left_ans
            left_ans[k] = left_ans.get(k,0)+ans_t[k] 
    #print(left_ans)
    for el in right:
        ans_t = analyze(el)
        for k in ans_t:     # 匯總到right_ans
            right_ans[k] = right_ans.get(k,0)+ans_t[k] 
    #print(right_ans)
     
    if right_ans == left_ans:
        print('Y')
    else:
        print('N')


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM