字节面试算法题输出化学式中每个原子的个数

2021.8.31 某同学的字节一面手撕算法题

给出类似于 HM2(H2ON3A)3N2 这样的类化学表达式
输出每个原子的个数

看起来有点意思

思路:

遇到左括号亚栈 有括号弹出栈
栈中存放固定大小为元素总数的数组,其记录每个元素的出现次数
同时主要到字母后面与右括号的数字,讲栈顶记录的出现次数与其相乘即可。

# 写上 所有 化学元素和 原子序数的对应 。这里比较懒先写几个用得到的
DIC = {
    'H': 0,
    'He': 1,
    'Li': 2,
    'C': 5,
    'O': 7,
    'S': 15,
    'Al': 12,
    'Cu': 29,
}

RE_DIC = {
    0: 'H',
    1: 'He',
    2: 'Li',
    5: 'C',
    7: 'O',
    15: 'S',
    12: 'Al',
    29: 'Cu',
}


def solve(s):
    stack = [[0] * 100]  # 化学元素先设定一百个吧。每个栈帧是个数组 数组按照元素顺序存放着元素的出现次数
    n = len(s)
    for idx, item in enumerate(s):
        if item.isupper(): # 化学元素名字总是一个大写字母开头后面都是小写字母

            # 支持多字符的元素,识别出类似于 Al Cu 这样的元素
            end = idx + 1
            while end <= n - 1 and s[end].islower():
                end += 1
            name = s[idx:end]

            # 记录右下缀 ,如 读出 Al2 中数字 2
            times = 1
            if end <= n - 1 and s[end].isdecimal():
                times = int(s[end])
            stack[-1][DIC[name]] += times

        elif item == '(': # 压栈
            stack.append([0] * 100)

        elif item == ')': # 出栈
            times = 1
            if idx != n - 1 and s[idx + 1].isdecimal():  # 如果 ) 后面是数字 要加倍
                times = int(s[idx + 1])
            popped = stack.pop()
            # 把弹出的信息,合并到栈顶中去
            for i in range(len(popped)):
                stack[-1][i] += popped[i] * times

    return stack


if __name__ == '__main__':
    # s = "Al2(SO4)3"
    s = "Cu2(OH)2CO3"
    ret = solve(s)
    for i in range(100):
        if ret[0][i] != 0:
            print(f"原子{RE_DIC[i]} : {ret[0][i]}")

输出

原子H : 2
原子C : 1
原子O : 5
原子Cu : 2
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值