# LeetCode: 726. 原子的数量¶

## 1、题目描述¶

输入:
formula = "H2O"



输入:
formula = "Mg(OH)2"



输入:
formula = "K4(ON(SO3)2)2"



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

## 2、解题思路¶

• 首先进行预处理

"Mg(OH)2"  => ['Mg', '(OH)2']
"((N42)24(OB40Li30CHe3O48LiNN26)33(C12Li48N30H13HBe31)21(BHN30Li26BCBe47N40)15(H5)16)14"
=>
['((N42)24(OB40Li30CHe3O48LiNN26)33(C12Li48N30H13HBe31)21(BHN30Li26BCBe47N40)15(H5)16)14']

'((N42)24(OB40Li30CHe3O48LiNN26)33(C12Li48N30H13HBe31)21(BHN30Li26BCBe47N40)15(H5)16)14'
=>
['(N42)24', '(OB40Li30CHe3O48LiNN26)33', '(C12Li48N30H13HBe31)21', '(BHN30Li26BCBe47N40)15', '(H5)16']


from string import ascii_lowercase, ascii_uppercase, digits
from collections import defaultdict

class Solution:
def countOfAtoms(self, formula: str) -> str:
if not formula:
return ""

lower = set(ascii_lowercase)
upper = set(ascii_uppercase)
nums = set(digits)

def get_atom(form):
pass

pre_processing = []

length = len(form)
pos = 0

temp = []

while pos < length:
current = form[pos]
if current in upper and not temp:
temp.append(current)
elif current in lower or current in nums:
temp.append(current)
elif current in upper and temp:
pre_processing.append("".join(temp))
temp = [current]
elif current == "(":
if temp:
pre_processing.append("".join(temp))
start = pos
stack = ["("]
pos += 1
while pos < length:
if form[pos] == ")":
stack.pop()
if not stack:
break
elif form[pos] == "(":
stack.append("(")

pos += 1
temp = [form[start:pos+1]]
pos += 1
if temp:
pre_processing.append("".join(temp))

result = defaultdict(int)
for s in pre_processing:
if s[0] == "(":
count = 1
if s[-1] in nums:
count = int(s[s.rindex(")") + 1:])

for atom, n in get_atom(s[1:s.rindex(")")]).items():
result[atom] += n * count

else:
if s[-1] in nums:
for index, char in enumerate(s):
if char in nums:
result[s[:index]] += int(s[index:])
break
else:
result[s] += 1
return result

res = get_atom(formula)
ans = []
for atom_name in sorted(res.keys()):
if res[atom_name] == 1:
ans.append(atom_name)

elif res[atom_name] > 1:
ans.append(atom_name + str(res[atom_name]))

return "".join(ans)