1. class Solution {
    2. public String countOfAtoms(String formula) {
    3. Map<String, Integer> map = new TreeMap<>();
    4. dfs(formula.toCharArray(), 0, map);
    5. StringBuilder sb = new StringBuilder();
    6. for(Map.Entry<String, Integer> entry : map.entrySet()) {
    7. sb.append(entry.getKey() + (entry.getValue() > 1 ? entry.getValue() : ""));
    8. }
    9. return sb.toString();
    10. }
    11. private int parseDigit(char[] chars, int i, StringBuilder sb) {
    12. while(i < chars.length && Character.isDigit(chars[i])) {
    13. sb.append(chars[i++]);
    14. }
    15. if(sb.length() == 0) {
    16. sb.append(1);
    17. }
    18. return i;
    19. }
    20. private int parseAtom(char[] chars, int i, StringBuilder sb) {
    21. sb.append(chars[i++]);
    22. while(i < chars.length && Character.isLowerCase(chars[i])) {
    23. sb.append(chars[i++]);
    24. }
    25. return i;
    26. }
    27. private int dfs(char[] chars, int i, Map<String, Integer> map) {
    28. while(i < chars.length) {
    29. if(chars[i] == ')') {
    30. return i + 1;
    31. }else if(chars[i] == '(') {
    32. Map<String, Integer> innerMap = new HashMap<>();
    33. i = dfs(chars, i + 1, innerMap);
    34. StringBuilder sb = new StringBuilder();
    35. i = parseDigit(chars, i, sb);
    36. int cnt = Integer.parseInt(sb.toString());
    37. innerMap.forEach((key, value) -> {
    38. map.put(key, map.getOrDefault(key, 0) + value * cnt);
    39. });
    40. }else {
    41. StringBuilder atom = new StringBuilder();
    42. StringBuilder digit = new StringBuilder();
    43. i = parseAtom(chars, i, atom);
    44. i = parseDigit(chars, i, digit);
    45. map.put(atom.toString(), map.getOrDefault(atom.toString(), 0) + Integer.parseInt(digit.toString()));
    46. }
    47. }
    48. return i;
    49. }
    50. }