CCF CSP 化学方程式 100分 python(栈和递归两种方法)

题目分析

元素个数=分子前面的数*原子后面的数*被包含括号后面的数

思路:
把方程式分成左右两个字符串,分别处理成字典(元素:个数),再比较字典是否相同

方法一:用栈
遍历字符串,遇到左括号进栈;遇到大写字母同样入栈,并用序号代替元素出入栈,获取其后面的数值;遇到‘+’则获得其后面的数字;遇到右括号出栈,获取其后面的数值

def elnum(s=''):
    shu=''
    for sshu in s:
        if sshu.isdigit():
            shu+=sshu
        else:
            break
    if shu:
        return eval(shu)
    else:
        return 1

def chuli(s=''): 
    cl={}
    elem_list=[]
    elem_num=[]    
    stack=[]
    elem_cnt=0
    cnt=elnum(s)
    for i in range(len(s)):
        if s[i].isupper():
            ss=s[i]
            if i<len(s)-1 and s[i+1].islower():
                i+=1
                ss+=s[i]
            elem_list.append(ss)    
            value=elnum(s[i+1:])#元素后面的数值
            stack.append(elem_cnt)
            elem_num.append(cnt*value)
            elem_cnt+=1
        elif s[i]=='(':
            stack.append(s[i])
        elif s[i]==')':
            value=elnum(s[i+1:])#括号后面的数值
            l=len(stack)-1
            tab=stack[l]
            while not tab=='(':
                elem_num[tab]*=value
                l-=1
                tab=stack[l]
            stack.pop(l)
        elif s[i]=='+':#分子前面的数值
            cnt=elnum(s[i+1:])
            
    for num in range(elem_cnt):#把相同元素的数值相加
        if cl.get(elem_list[num]):
            cl[elem_list[num]]+=elem_num[num]
        else:
            cl[elem_list[num]]=elem_num[num]
    return cl  
    
n=eval(input())
for i in range(n):
    s=input()
    s1,s2=s.split('=')
    if chuli(s1)==chuli(s2):
        print('Y')
    else:
        print('N')

方法二:递归

def elnum(s=''):
    shu=''
    for sshu in s:
        if sshu.isdigit():
            shu+=sshu
        else:
            break
    if shu:
        return int(shu)
    else:
        return 1
    
def digui(cdick,s='',i=0):
    while i<len(s):
        if s[i]==')':
            value=elnum(s[i+1:])#括号后面的数值
            return value,i
        elif s[i]=='(':
            cl={}
            value,i=digui(cl,s,i+1)
            for k in cl.keys():
                if cdick.get(k):
                    cdick[k]+=cl[k]*value
                else :
                    cdick[k]=cl[k]*value
        elif s[i].isupper():
            ss=s[i]
            if i<len(s)-1 and s[i+1].islower():
                i+=1
                ss+=s[i]  
            value=elnum(s[i+1:])#元素后面的数值
            if cdick.get(ss):
                cdick[ss]+=value
            else:
                cdick[ss]=value
        i+=1
    return 1,i

def chuli(ss=''): 
    cdick={}
    slist=ss.split('+')
    for s in slist:
        cl={}
        cnt=elnum(s)
        digui(cl,s,0)
        for k in cl.keys():
            if cdick.get(k):
                cdick[k]+=cl[k]*cnt
            else:
                cdick[k]=cl[k]*cnt
    return cdick  
    
n=eval(input())
for i in range(n):
    s=input()
    s1,s2=s.split('=')
    if chuli(s1)==chuli(s2):
        print('Y')
    else:
        print('N')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值