给出一个字符串格式的化学分子式,计算原子的个数
每个化学元素都是由一个大写字母,或者一个大写字母后跟着若干个小写字母组成,例如H是一个化学元素,Mg也是一个化学元素。
每个分子式中,原子的个数写在元素后面,如果原子个数是1,那么原子个数省略。例如H2O和H2O2都是有效的分子式,但H1O2不是有效分子式。
每个分子式中包含若干括号,为简单起见,分子式中只有小括号。
每次输入一个分子式,对每个给定的分子式,求出每个原子的个数,按照原子字母表的顺序排列,并输出。
一行,一个字符串表示输入的分子式
按要求输出答案
H2O
H2O
Mg(OH)2
H2MgO2
K4(ON(SO3)2)2
K4N2O14S4
class MainActivity:
def main(self):
# Read the data
s = input()
# Get the results
results = self.__traverse(s)
# Construct the result
results = sorted(list(results.items()), key=lambda x: x[0])
results = list(map(lambda x: '%s%d' % (x[0], x[1]) if x[1] > 1 else x[0], results))
result = ''.join(results)
print(result)
def __traverse(self, s):
# Initialization
results = dict()
cnt = 0
elementCache = []
ptr = 0
# Traverse
while ptr < len(s):
char = s[ptr]
if ord('A') <= ord(char) <= ord('Z'):
if cnt and elementCache:
element = ''.join(elementCache)
if cnt > 1:
cnt = int(str(cnt)[1:])
results[element] = results.get(element, 0) + cnt
cnt = 1
elementCache = [char]
ptr += 1
elif ord('a') <= ord(char) <= ord('z'):
elementCache.append(char)
ptr += 1
elif char.isnumeric():
cnt = cnt * 10 + int(char)
ptr += 1
else: # (
# Add the cache first
if cnt and elementCache:
element = ''.join(elementCache)
if cnt > 1:
cnt = int(str(cnt)[1:])
results[element] = results.get(element, 0) + cnt
elementCache = []
cnt = 1
# Cope with the content in the bracket
bracketCnt = 1
cacheS = []
ptr += 1
while bracketCnt:
cacheS.append(s[ptr])
if bracketCnt and s[ptr] == ')':
bracketCnt -= 1
elif s[ptr] == '(':
bracketCnt += 1
ptr += 1
cacheS.pop() # Remove the outer ')'
subS = ''.join(cacheS)
subResult = self.__traverse(subS)
while ptr < len(s) and s[ptr].isnumeric():
cnt = cnt * 10 + int(s[ptr])
ptr += 1
if cnt > 1:
cnt = int(str(cnt)[1:])
for element, times in subResult.items():
results[element] = results.get(element, 0) + times * cnt
if cnt:
element = ''.join(elementCache)
if cnt and element:
if cnt > 1:
cnt = int(str(cnt)[1:])
results[element] = results.get(element, 0) + cnt
return results
if __name__ == '__main__':
M = MainActivity()
M.main()