• 算法48---原子的数量【栈】


    一、题目:原子的数量

    给定一个化学式formula(作为字符串),返回每种原子的数量。

    原子总是以一个大写字母开始,接着跟随0个或任意个小写字母,表示原子的名字。

    如果数量大于 1,原子后会跟着数字表示原子的数量。如果数量等于 1 则不会跟数字。例如,H2O 和 H2O2 是可行的,但 H1O2 这个表达是不可行的。

    两个化学式连在一起是新的化学式。例如 H2O2He3Mg4 也是化学式。

    一个括号中的化学式和数字(可选择性添加)也是化学式。例如 (H2O2) 和 (H2O2)3 是化学式。

    给定一个化学式,输出所有原子的数量。格式为:第一个(按字典序)原子的名子,跟着它的数量(如果数量大于 1),然后是第二个原子的名字(按字典序),跟着它的数量(如果数量大于 1),以此类推。

    示例 1:

    输入: 
    formula = "H2O"
    输出: "H2O"
    解释: 
    原子的数量是 {'H': 2, 'O': 1}。
    

    示例 2:

    输入: 
    formula = "Mg(OH)2"
    输出: "H2MgO2"
    解释: 
    原子的数量是 {'H': 2, 'Mg': 1, 'O': 2}。
    

    示例 3:

    输入: 
    formula = "K4(ON(SO3)2)2"
    输出: "K4N2O14S4"
    解释: 
    原子的数量是 {'K': 4, 'N': 2, 'O': 14, 'S': 4}。
    

    注意:

    • 所有原子的第一个字母为大写,剩余字母都是小写。
    • formula的长度在[1, 1000]之间。
    • formula只包含字母、数字和圆括号,并且题目中给定的是合法的化学式。

    思路:时间O(n),空间O(n)

    采用一个栈,存储数字

    从后往前遍历: for s in formula[::-1]

    (1)遇到数字,则令 num = 数字* (10^i ),【存在连续两个数字出现,如“Be32”】故采用 i 来判断,如果前面一个字母不是数字,则 i = 0, 否则,i+=1。

    即 if s.isdigit():

      num += int(s)*(10**i)

      i += 1

    (2)遇到 ')'则将 num数字加入栈 stack 中,因为数字存在两种情况,【如‘H4(CO3)2’,像3和4是不用存到栈中,2要存进stack中】,故遇到 )才将num存进stack中。然后令num=0,i=0

    即 if s == ')':

      stack.append(num)

      num = i = 0

    (3)遇到‘(’,则将栈最后一个元素删除,因为【‘H2(CO3(CaO)4)2’】,此时stack中应该为【4,2】,遇到第一个(将2弹出,因为CO3对应的系数应为2,而CaO对应的系数为4*2=8。

    即 if s == '(':

      stack.pop()

      num = i = 0

    (4)大写字母,则将完整字母,【‘Mg'】存入字典中,其对应的系数为栈中所有数相乘的结果,如果字典中原来存在的话就将原来的系数加上,

    其余条件初始化:num = i = 0,string = ’‘【小写字母】,count = 1【栈中所有的数相乘结果】

    即 if s.isupper():

      string += s
           count = num if num else 1  #像【‘H2(CO3(CaO)4)2’】count=3,再与栈中所有数相乘
    #栈中所有数相乘      

      for m in stack:  
             count *= m

    # 将结果存入字典中
           if string[::-1] in dic:
                 dic[string[::-1]] += count
            else:
                 dic[string[::-1]] = count

    #初始化
            string = ''
            count,num,i= 1,0,0

    (5)小写字母,与之前的字母相加起来

    即 if s.islower():

      string += s

    代码:

        def countOfAtoms(self, formula):
            """
            :type formula: str
            :rtype: str
            """
            if not formula:
                return ""
            stack = []
            dic = {}
            string = ''
            count,num,i = 1,0,0
            for s in formula[::-1]:
                if s.isdigit():
                    num += int(s)*(10**i)
                    i+=1
                elif s == ')':
                    stack.append(num)
                    num = 0
                    i=0
                elif s == '(':
                    stack.pop()
                    i ,num= 0,0
                elif s.isupper():
                    string += s 
                    count = num if num else 1
                    for m in stack:
                        count *= m
                    if string[::-1] in dic:
                        dic[string[::-1]] += count
                    else:
                        dic[string[::-1]] = count
                    string = ''
                    count,num = 1,0
                    i = 0
                elif s.islower():
                    string += s
            sort = sorted(dic.items(),key = lambda x:x[0])
            res = ''
            for item in sort:
                res += item[0]
                if item[1]>1:
                    res += str(item[1])
            return res
  • 相关阅读:
    JavaScript HTML 输入示例(Input)
    JS Web API
    JavaScript DOM 示例
    JavaScript浏览器对象示例
    JavaScript示例
    JavaScript HTML DOM 事件示例
    JavaScript ES(610)语法大全
    JavaScript HTML 对象示例(Objects Examples)
    Windows下安装RabbitMQ
    ABP框架入门学习(五)——权限配置
  • 原文地址:https://www.cnblogs.com/Lee-yl/p/9948726.html
Copyright © 2020-2023  润新知