给出一个字符串格式的化学分子式,计算原子的个数
每个化学元素都是由一个大写字母,或者一个大写字母后跟着若干个小写字母组成,例如H是一个化学元素,Mg也是一个化学元素。
每个分子式中,原子的个数写在元素后面,如果原子个数是1,那么原子个数省略。例如H2O和H2O2都是有效的分子式,但H1O2不是有效分子式。
每个分子式中包含若干括号,为简单起见,分子式中只有小括号。
每次输入一个分子式,对每个给定的分子式,求出每个原子的个数,按照原子字母表的顺序排列,并输出。
一行,一个字符串表示输入的分子式
按要求输出答案
H2O
H2O
Mg(OH)2
H2MgO2
K4(ON(SO3)2)2
K4N2O14S4
import java.util.*; // 栈 + Map计数 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String s = in.next(); char[] c = s.toCharArray(); Deque<Map<String, Integer>> stack = new LinkedList<>(); int n = c.length; for (int i = 0; i < n;) { if (Character.isUpperCase(c[i])) { int j = i + 1; while (j < n && Character.isLowerCase(c[j])) j++; String key = s.substring(i, j); int num = 0; while (j < n && Character.isDigit(c[j])) { num = num * 10 + c[j] - '0'; j++; } i = j; num = num == 0 ? 1 : num; Map<String, Integer> map = new HashMap<>(); map.put(key, num); stack.push(map); } else if (c[i] == '(') { Map<String, Integer> map = new HashMap<>(); map.put("(", -1); stack.push(map); i++; } else { // 遇到 ) 要合并 () 里面的并找到与之匹配的 ( int num = 0, j = i + 1; while (j < n && Character.isDigit(c[j])) { num = num * 10 + c[j] - '0'; j++; } i = j; num = num == 0 ? 1 : num; Map<String, Integer> map = new HashMap<>(); while (!stack.peek().containsKey("(")) { Map<String, Integer> mp = stack.pop(); for (String key : mp.keySet()) { map.merge(key, mp.get(key) * num, Integer::sum); } } stack.pop(); stack.push(map); } } Map<String, Integer> map = new HashMap<>(); // 合并栈内剩余的 while (!stack.isEmpty()) { Map<String, Integer> mp = stack.pop(); for (String key : mp.keySet()) { map.merge(key, mp.get(key), Integer::sum); } } List<String> list = new ArrayList<>(map.keySet()); // 字典序 Collections.sort(list); StringBuilder sb = new StringBuilder(); for (String key : list) { sb.append(key); int val = map.get(key); if (val > 1) sb.append(val); } System.out.println(sb.toString()); } }