首页 > 试题广场 >

计算原子的个数

[编程题]计算原子的个数
  • 热度指数:831 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
给出一个字符串格式的化学分子式,计算原子的个数
每个化学元素都是由一个大写字母,或者一个大写字母后跟着若干个小写字母组成,例如H是一个化学元素,Mg也是一个化学元素。
每个分子式中,原子的个数写在元素后面,如果原子个数是1,那么原子个数省略。例如H2O和H2O2都是有效的分子式,但H1O2不是有效分子式。
每个分子式中包含若干括号,为简单起见,分子式中只有小括号。
每次输入一个分子式,对每个给定的分子式,求出每个原子的个数,按照原子字母表的顺序排列,并输出。

输入描述:
一行,一个字符串表示输入的分子式


输出描述:
按要求输出答案
示例1

输入

H2O

输出

H2O
示例2

输入

Mg(OH)2

输出

H2MgO2
示例3

输入

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()
发表于 2024-09-02 16:53:28 回复(0)