1. 程式人生 > 其它 >726. 原子的數量

726. 原子的數量

給你一個字串化學式 formula ,返回 每種原子的數量 。

原子總是以一個大寫字母開始,接著跟隨 0 個或任意個小寫字母,表示原子的名字。

如果數量大於 1,原子後會跟著數字表示原子的數量。如果數量等於 1 則不會跟數字。

例如,"H2O" 和 "H2O2" 是可行的,但 "H1O2" 這個表達是不可行的。
兩個化學式連在一起可以構成新的化學式。

例如 "H2O2He3Mg4" 也是化學式。
由括號括起的化學式並佐以數字(可選擇性新增)也是化學式。

例如 "(H2O2)" 和 "(H2O2)3" 是化學式。
返回所有原子的數量,格式為:第一個(按字典序)原子的名字,跟著它的數量(如果數量大於 1),然後是第二個原子的名字(按字典序),跟著它的數量(如果數量大於 1),以此類推。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/number-of-atoms
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

import java.util.*;

class Solution {
    int index = 0;
    String formula;

    private void merge(Map<String, Integer> map1, Map<String, Integer> map2) {
        for (Map.Entry<String, Integer> entry : map2.entrySet()) {
            map1.put(entry.getKey(), map1.getOrDefault(entry.getKey(), 0) + entry.getValue());
        }
    }

    private Map<String, Integer> multiply(Map<String, Integer> map, int num) {
        if (num == 1) {
            return map;
        }
        Map<String, Integer> ret = new HashMap<>();
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            ret.put(entry.getKey(), entry.getValue() * num);
        }

        return ret;
    }

    private void addToMap(Map<String, Integer> map, String str, int num) {
        map.put(str, map.getOrDefault(str, 0) + num);
    }

    public String countOfAtoms(String formula) {
        this.index = 0;
        this.formula = formula;

        Stack<Map<String, Integer>> stack = new Stack<>();
        stack.push(new HashMap<>());

        while (index < formula.length()) {
            if (formula.charAt(index) == '(') {
                stack.push(new HashMap<>());
                index++;
            } else if (formula.charAt(index) == ')') {
                index++;
                int num = getNum();
                Map<String, Integer> m1 = stack.pop();
                Map<String, Integer> m2 = stack.peek();
                m1 = multiply(m1, num);
                merge(m2, m1);
            } else {
                addToMap(stack.peek(), getString(), getNum());
            }
        }

        Map<String, Integer> pop = stack.pop();
        TreeMap<String, Integer> treeMap = new TreeMap<>(pop);
        StringBuilder ret = new StringBuilder();

        for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
            ret.append(entry.getKey());
            if (entry.getValue() > 1) {
                ret.append(entry.getValue());
            }
        }

        return ret.toString();

    }

    private int getNum() {
        if (index == formula.length() || !Character.isDigit(formula.charAt(index))) {
            return 1;
        }
        int num = 0;
        while (index < formula.length() && Character.isDigit(formula.charAt(index))) {
            num = num * 10 + formula.charAt(index++) - '0';
        }
        return num;
    }

    private String getString() {
        StringBuilder ret = new StringBuilder();
        ret.append(formula.charAt(index++));
        while (index < formula.length() && Character.isLowerCase(formula.charAt(index))) {
            ret.append(formula.charAt(index++));
        }
        return ret.toString();
    }


    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            System.out.println(new Solution().countOfAtoms(in.next()));
        }
    }

}
心之所向,素履以往 生如逆旅,一葦以航