首页 > 试题广场 >

计算原子的个数

[编程题]计算原子的个数
  • 热度指数:859 时间限制: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
Stack里面套Map,方便合并
遇到 ( 入栈
遇到 ) 就出栈合并,直到弹出 (
计算表达式也差不多这样
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());
    }
}



发表于 2025-06-29 09:16:12 回复(0)